我尝试将C++属性实现为WikiPedia中定义的模板
template <typename T> class property {
T value;
public:
T & operator = (const T &i) {
::std::cout << i << ::std::endl;
return value = i;
}
// This template class member function template serves the purpose to make
// typing more strict. Assignment to this is only possible with exact identical
// types.
template <typename T2> T2 & operator = (const T2 &i) {
::std::cout << "T2: " << i << ::std::endl;
T2 &guard = value;
throw guard; // Never reached.
}
operator T const & () const {
return value;
}
};现在假设我声明了两个类,其中一个类包含另一个类作为属性:
class A
{
public:
Property<double> pA1;
Property<double> pA2;
};
class B
{
public:
Property<A> pB1;
Property<double> pB2;
};现在,是否有一种方法来声明一个B并在其中访问A的属性?
B b;
b.pB1.pA1=1;不起作用;
((A) b.pB1).pA1=1;工作w/o错误,但实际上并没有更改实际的A of B,因为添加((A) b.pB1).pA1给出了不变的值,因为它可能会生成副本。
有什么方法可以做到这一点吗?
发布于 2010-09-27 20:38:33
将一个对象转换为另一个类型会产生一个临时副本,一旦代码行完成,该副本就会超出范围。你是想写((A&) b.pB1).pA1=1;吗?
发布于 2010-09-27 22:21:55
b.pB1没有pA1字段。相反,它有b.pB1.value.pA1。使用".“实际上调用“成员访问操作符”,绕过类型转换运算符。显式类型转换可以工作,但从长远来看并不是安全代码:
((A&)b.pB1).pA1 = 1.0;更好的方法是实现成员访问操作员。它也破坏了封装(因为运算符可以显式调用),但与显式类型转换相比要安全得多:
T* operator->() { return &value; }
...
b.pB1->pA1 = 3.0;完整的例子:
#include <iostream>
using namespace std;
template <typename T>
class Property
{
T value;
public:
T& operator=(const T& x) {
return value = x;
}
template <typename T2>
T2 & operator = (const T2 &i) {
T2 &guard = value;
throw guard; // Never reached
}
operator T const & () const { return value; }
const T* operator->() const { return &value; }
T* operator->() { return &value; }
};
class A
{
public:
Property<double> pA1;
Property<double> pA2;
};
class B
{
public:
Property<A> pB1;
Property<double> pB2;
};
int
main()
{
B b;
//b.pB2 = 1; // not allowed by guard
b.pB2 = 1.0;
((A&)b.pB1).pA1 = 2.0;
cout << "b.pB1.pA1: " << ((A&)b.pB1).pA1 << endl;
b.pB1->pA1 = 3.0;
b.pB1->pA2 = 4.0;
cout << "b.pB1.pA1: " << b.pB1->pA1 << endl;
cout << "b.pB1.pA2: " << b.pB1->pA2 << endl;
return 0;
}发布于 2010-09-27 21:34:49
您试过添加非const函数运算符吗?
operator T& ()
{
return value;
}这破坏了封装,但您的示例用法表明您希望能够修改属性。
https://stackoverflow.com/questions/3807600
复制相似问题