2013-11-24 44 views
2

假设我有我的课为:设置从另一个类只读属性

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方法+干将。

但是我不希望(使用API​​或某人)设置A.a任何其他范围,所以公共setter方法被用于这种情况下禁止

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

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

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

+5

理念1,定义带有'int'的公共'explicit'构造函数的'A'。想法2,让'B'成为'A'的朋友。你说你尝试过“朋友”,但我怀疑你没有努力。 –

+2

int的默认构造是未定义的值。 如果你想要别的东西,添加合适的构造函数。 (例如,设置好值的无参数构造函数,或者接受参数并使用它的int构造函数)。 至于显式,它不需要,但通常是一个arg构造函数的好主意,以避免无意的自动转换 – RichardPlunkett

回答

2

你想让B有机会获得A,你不想让其他人拥有?

这就是友谊。

friend class B,进入A级定义,一切都会幸福。

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

被警告,大多数人应该很少或永远不会使用朋友,它主要用于图书馆编写者,而不是用于一般编程。

1

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

这里是友谊的工作例如:

#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它丑陋:-)

#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); 
} 

};