English 中文(简体)
保护外界资源
原标题:Protected External Resource Usage

I m working with some code where I have the following setup.

struct data
{
      void change_safe_member(){}
      void read_data(){}
      void change_unsafe_member(){}
};

struct data_processor
{
     std::shared_ptr<data> get_data(){}
     void return_data(std::shared_ptr<data> my_data)
     {
           my_data->change_unsafe_member(); // ONLY data_processor should call this function.
     }
};

struct client
{
     void foo(std::shared_ptr<data_processor>& my_processor)
     {
           auto my_data = my_processor->get_data();
           my_data->change_safe_member();
           //my_data->change_unsafe_member(); SHOULD NOT BE POSSIBLE TO CALL
           my_processor->return_data(my_data);
     }
};

改变“unsafe”成员只能由处理人内部使用,因此,我要隐瞒这种变化,或者让客户失望。 但是,我不知道在不诉诸于丑恶之s的情况下这样做的极端方法。

struct internal_data
{
      void change_unsafe_member(){}
};

struct data : public internal_data
{
      void change_safe_member(){}
      void read_data(){}
};

struct data_processor
{
     std::shared_ptr<data> get_data(){}
     void return_data(std::shared_ptr<data> my_data)
     {
           auto internal_data = std::static_pointer_cast<internal_data>(my_data);
           internal_data->change_unsafe_member(); 
     }
};

Anyone know of a good pattern to use in situations like this? Maybe visitor pattern or something similar?

EDIT:

正如在评论中指出的,人们可以宣布朋友班级,但有一个问题,即:以下工作不会奏效。

struct data
{
      void change_safe_member(){}
      void read_data(){}
private:
      friend class data_processor;
      virtual void change_unsafe_member(){}
};

struct data_decorator : public data
{
      data_decorator(const std::shared_ptr<data>& decoratee) : decoratee_(decoratee){}
      void change_safe_member(){decoratee_->change_safe_member();}
      void read_data(){decoratee_->read_data();}
private:
      virtual void change_unsafe_member()
      {
             std::cout << "Hello!"; // Add functionality
             decoratee_->change_unsafe_member(); // Won t work... compiler error
      }
      std::shared_ptr<data> decoratee_;
};

// Another example
struct data_group_decorator : public data
{
      data_group_decorator (const std::vector<std::shared_ptr<data>>& decoratees) : decoratees_(decoratees){}
      void change_safe_member(){decoratee_->change_safe_member();}
      void read_data(){decoratee_->read_data();}
private:
      virtual void change_unsafe_member()
      {
             for(size_t n = 0; n < decoratees_.size(); ++n)
                   decoratees_[n]->change_unsafe_member(); // Won t work... compiler error
      }
      std::vector<std::shared_ptr<data>> decoratees_;;
};
最佳回答

你可以通过继承来做到这一点。

struct Y;
struct X {
    friend struct Y;
private:
    change_unsafe_member() {}
};
struct Y {
protected:
    change_unsafe_member(X& x) { x.change_unsafe_member(); }
};
struct some_other : Y {
    X x;
    change_safe_member() { change_unsafe_member(x); }
};

任何从Y继承的阶层,都可以就Y所定义的有效从X转出的职能取得X的友谊。

问题回答

Your last example looks like what you re really asking for is inherited friendship; i.e. you want to have a hierarchy of decorator - derived classes which are all allowed to call the private member function in data. That s answered (with "generally no") elsewhere:

为什么C++不允许继承的友谊?

多种形态可能会在您的具体设想中提供某种救济,使<代码>级数据_decorator 成为“几乎纯净”虚拟基类,只有非虚拟成员成为protected change_unsafe_member(,从而使之成为bian/code>>>>>>>。 所有校友都将继承<条码>数据_decorator,并称其受保护的非虚拟成员。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?