属性作为模板的属性 我尝试将C++属性作为在中定义的模板实现

属性作为模板的属性 我尝试将C++属性作为在中定义的模板实现,c++,properties,C++,Properties,不工作,不工作 ((A) b.pB1).pA1=1; 在没有错误的情况下工作,但实际上不会更改B的实际A,因为accesing((A)B.pB1).pA1给出的值不变,因为它可能会生成副本 有没有一种不使用指针的方法?将一个对象强制转换为另一种类型会导致一个临时副本,该副本在该行代码完成后立即超出范围。你的意思是写((A&)b.pB1.pA1=1?将一个对象强制转换为另一种类型会导致一个临时副本,该副本在该行代码完成后立即超出范围。你的意思是写((A&)b.pB1.pA1=1?是否尝试添加非常

不工作,不工作

((A) b.pB1).pA1=1;
在没有错误的情况下工作,但实际上不会更改B的实际A,因为accesing((A)B.pB1).pA1给出的值不变,因为它可能会生成副本


有没有一种不使用指针的方法?

将一个对象强制转换为另一种类型会导致一个临时副本,该副本在该行代码完成后立即超出范围。你的意思是写
((A&)b.pB1.pA1=1

将一个对象强制转换为另一种类型会导致一个临时副本,该副本在该行代码完成后立即超出范围。你的意思是写
((A&)b.pB1.pA1=1

是否尝试添加非常量函数运算符

operator T& () 
{
    return value;
}

这会破坏封装,但您的示例用法表明您希望能够修改属性。

您是否尝试添加非常量函数运算符

operator T& () 
{
    return value;
}

这会破坏封装,但您的示例用法表明您希望能够修改属性。

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;
}
#包括
使用名称空间std;
模板
类属性
{
T值;
公众:
T和运算符=(常数T和x){
返回值=x;
}
模板
T2和运算符=(常数T2和i){
T2&保护=值;
扔卫兵;//永远够不着
}
运算符T常量&()常量{返回值;}
常量T*运算符->()常量{return&value;}
T*运算符->(){return&value;}
};
甲级
{
公众:
财产pA1;
财产pA2;
};
B类
{
公众:
属性pB1;
属性pB2;
};
int
main()
{
B B;
//b、 pB2=1;//警卫不允许
b、 pB2=1.0;
((A&)b.pB1.pA1=2.0;

coutb.pB1没有pA1字段。相反,它有b.pB1.value.pA1.Using.“.”实际上调用“成员访问运算符”,绕过类型转换运算符。显式类型转换可以工作,但从长远来看不是安全代码:

((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;
}
#包括
使用名称空间std;
模板
类属性
{
T值;
公众:
T和运算符=(常数T和x){
返回值=x;
}
模板
T2和运算符=(常数T2和i){
T2&保护=值;
扔卫兵;//永远够不着
}
运算符T常量&()常量{返回值;}
常量T*运算符->()常量{return&value;}
T*运算符->(){return&value;}
};
甲级
{
公众:
财产pA1;
财产pA2;
};
B类
{
公众:
属性pB1;
属性pB2;
};
int
main()
{
B B;
//b、 pB2=1;//警卫不允许
b、 pB2=1.0;
((A&)b.pB1.pA1=2.0;

什么不起作用意味着什么?givs是一个错误?什么不起作用意味着什么?givs是一个错误?有没有办法在B中创建一个直接引用pA1的属性?比如属性pA1_in_B=((a&)this->pB1).pA1;@paul,我认为
pA1_in_B
必须声明为该代码的引用,才能实现您所期望的功能。理论上,您也可以将整个混乱的地址作为指针。有没有办法在B中创建一个直接引用pA1的属性?比如pA1_in_B=((a&)this->pB1)中的属性.pA1;@paul,我认为
pA1_in_B
必须声明为该代码的引用,才能实现您期望的功能。理论上,您也可以将整个混乱的地址作为指针。