从另一个类设置readonly属性

时间:2013-11-24 00:11:03

标签: c++ readonly

假设我的课程为:

namespace scope
{

class A
{
private:
    int a;
public:
    ...
};

class B
{
public:
    ...
    A method();
    ...
};

};

方法定义:

A B::method()
{
    A object;
    object.a = 3;    // private member access error
                     // access via object (pointer) error if inheritance is used
    return object;
}

解决访问错误的最常用方法是使用setter + getters。

但是我不希望任何其他范围(或使用API​​的人)设置A.a,因此对于这种情况,公共设置器方法被禁止

a 可能是公开的,但在API端应该是只读的。它应该在源端读取+写入,因为,例如,我想用B::method设置它。 如何实现此行为?

我试过继承,也是朋友关系。我还玩过immutableconst属性声明。这些问题是,当我使用默认构造函数声明一个对象时,属性被设置为某个值,如-918316838410(可能是因为我没有使用extern,我不确定)并且稍后无法通过method设置。

任何想法将不胜感激。提前谢谢。

2 个答案:

答案 0 :(得分:2)

您希望B能够访问您不希望其他人拥有的A吗?

那是友谊。

friend class B添加到A类定义中,所有这些都将是幸福。

btw这个常见的例子就是当我使用多个类来生成单个接口时。例如:list<>之类的东西和地图<>通常需要节点类,而这些类通常需要朋友互相访问。这种封装的破坏很好,因为从逻辑的角度来看它们确实是一个大类。

请注意,大多数人应该很少或永远不会使用朋友,主要是图书馆作家,而不是一般编程。

答案 1 :(得分:1)

就像理查德所说,你可以使用友谊。但请记住,当你需要友谊时,你应该再考虑一下你的设计。正如理查德所说,也许把一个作为A构造函数的参数应该完全按照你想要的那样做。

以下是友谊的工作示例:

#include <iostream>
namespace scope
{
class A{
friend class B;
private:
    int a;
public:
    void print(){ 
        std::cout << a << std::endl;
    }
};

class B{
public:
    A method(){
        A a;
        a.a=3;
        return a;
    }
};

int main(){
    scope::B b;
    scope::A a = b.method();
    a.print(); //just to see it works...
}

这是一种在没有友谊和保持私密的情况下做同样事情的方法(Ok it ugly :-)

#include <iostream>
namespace scope
{
class B;
class A
{
private:
    int a;
public:
    void print(){
        std::cout << a << std::endl;
    }
    // A way to only allow B instances to give a correct value 
    // of "a" member
    void pleaseClassBSetMyPrivateMember(B& b);
};

class B
{
public:
    A method(){
        A a;
        a.pleaseClassBSetMyPrivateMember(*this);
        return a;
    }

    int computeValueForMemberOfClassA(A& a){
        // you can access public members of a to 
        // calculate the proper value of a.a member
        return 3;
    }

};

void A::pleaseClassBSetMyPrivateMember(B& b)
{
   // ask for class B object the correct value for member a
   a = b.computeValueForMemberOfClassA(*this);
}

};