Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将类的属性泄漏给它';s组件_C++_Oop_Composition - Fatal编程技术网

C++ 将类的属性泄漏给它';s组件

C++ 将类的属性泄漏给它';s组件,c++,oop,composition,C++,Oop,Composition,我有以下课程: class A { // Whatever }; class B { T attribute; A a; }; 现在假设我有以下场景: A aX, aY; B bX, bY; 现在我可以通过将aX或aY插入bX或 我想让类型A的对象知道,它们在什么B中,或者换句话说,它们的“超类”B的“属性”是什么 问题: 我希望能够在它们的“超类”B之间自由移动类型A的对象,并且我需要一种方法在运行时动态地将B的属性泄漏给它们,,这样类型A的对象总是知道它

我有以下课程:

class A {
    // Whatever
};

class B {
    T attribute;
    A a;
};
现在假设我有以下场景:

A aX, aY;  
B bX, bY;  
现在我可以通过将
aX
aY
插入
bX

我想让类型A的对象知道,它们在什么B中,或者换句话说,它们的“超类”B的“
属性”是什么

问题:

我希望能够在它们的“超类”B之间自由移动类型A的对象,并且我需要一种方法在运行时动态地将B的属性泄漏给它们,,这样类型A的对象总是知道它们属于什么B(或者它们当前所在的B的属性是什么)


最好的方法是什么?

您可以给
A
一个指向它的
B
父项的指针:

将“B”类定义为接口。生成“getAttribute”方法,并将“B”的指针设置为“A”类的实例。现在您可以创建“B”类的子类,并向其添加“A”类,“A”类始终可以知道“B”的属性

也许这很有用(从所有者指向属性的指针,反之亦然):


更新:修复了循环指向和循环调用中的一个错误,它只能通过友元函数解决。

您可以在
a
中设置指向
B
的指针,并在
B
中引用
a
直接从
a
对象获取所需内容:

#include <iostream>

class B;

class A {
    B *_b;
public:
    void setB(B *b) {
        _b = b;
    }

    B *getB() {
        return _b;
    }
};

class B {
    int _attribute;
    A &_a;
public:
    B(A& a, int attribute) : _attribute(attribute), _a(a) {
        _a.setB(this);
    }

    int getAttribute() {
        return _attribute;
    }
};

int main(int argc, const char *argv[])
{
    A a1;
    B b1(a1, 5);

    A a2;
    B b2(a2, 10);

    std::cout << a1.getB()->getAttribute() << std::endl;
    std::cout << a2.getB()->getAttribute() << std::endl;

    return 0;
} 

我已经编辑了我的答案,现在没有bug了。
class A 
{
    // Whatever
    B* pointerToB;
    void setB(B* b){ pointerToB = b; }
};

class B 
{
    virtual void someMethod() = 0;
    void addA(A* a)
    {
       a->setB(this);
       this->a = *a;
    }  
    T getAttribute(){ return attribute; }
    T attribute;
    A a;
};

class BB : public B {} // define BB's someMethod version or more method's
class A;

class B {
    T attribute;
    A* a;
public:
   void setA(A* newA);
   T getAttribute() {return attribute;}
   void setAttribute() {/*some code*/}
};

class A {
   B* Owner;
   friend void B::setA(A* newA);
public:
    void setOwner(B* newOwner) {
        newOwner->setA(this);
    }
};

void B::setA(A* newA)
{
    A* tempA = this->a;
    B* tempB = newA->Owner;

    tempA->Owner = NULL;
    tempB->a = NULL;

    this->a = newA;
    newA->Owner = this;
}
#include <iostream>

class B;

class A {
    B *_b;
public:
    void setB(B *b) {
        _b = b;
    }

    B *getB() {
        return _b;
    }
};

class B {
    int _attribute;
    A &_a;
public:
    B(A& a, int attribute) : _attribute(attribute), _a(a) {
        _a.setB(this);
    }

    int getAttribute() {
        return _attribute;
    }
};

int main(int argc, const char *argv[])
{
    A a1;
    B b1(a1, 5);

    A a2;
    B b2(a2, 10);

    std::cout << a1.getB()->getAttribute() << std::endl;
    std::cout << a2.getB()->getAttribute() << std::endl;

    return 0;
} 
5
10