使用* this在初始化期间将对象的实例传递给成员

时间:2014-08-03 05:45:33

标签: c++ initialization this

在传递类A的类实例的this指针时遇到一些麻烦。这里的目标是让B类可以访问类A实例objA的成员。

class B
{
public:
    B(A _objA)
        : objA(_objA) {;}

        A objA;
};

class A
{
public:
    A() : objB(*this) {;}

    B objB;
};


int main() {
    A Object;
}

编译这个给出 错误C2061:语法错误:标识符'A'

在没有运气的情况下尝试了Pass 'this' object to an initialization list以供参考。它只是一个链接问题吗?

2 个答案:

答案 0 :(得分:4)

那不行。 A包含B的实例,B包含A的实例。没有办法构造任何一种类型的对象,因为它们是递归定义的。

另一个问题是你在*this的构造函数的初始化列表中通过值传递A。这将调用A的复制构造函数,这将导致未定义的行为,因为A的实例尚未完全构造。

答案 1 :(得分:2)

正如其他人所说,A在使用之前没有定义。但是,您可以使用A的前向声明来允许B包含对A的引用。它仍然是B的类定义中的不完整类型。但是您可以将B&#39的构造函数移到类定义之外。 A类将是一个完整的类型,您可以访问它的成员。例如:

// forward declaration 
class A;

class B
{
public:
    B(A &_objA);

        // reference
        A &objA;
};

class A
{
public:
    A() : objB(*this) {;}

    B objB;
    int count;
};

// implementation moved outside of the class definition
B::B(A &_objA) : objA(_objA)
{
    // class A is now a complete type and we can access
    // elements using the reference
    objA.count = 42;
}

int main() {
    A Object;
}

*编辑

如果要将类定义放在头文件中,则有几个选项。您可以拥有一个与上面的代码示例非常相似的公共头文件。或者,您可以为每个类定义创建一个头文件。只需确保以正确的顺序包含头文件。

/* header file A.h */
#ifndef __A_H
#define __A_H

// class A needs the definition of class B
#include "B.h"

class A
{
public:
    A();

    B objB;
    int count;
};
#endif /* __A_H */

不要忘记B&#39的头文件中的前向声明:

/* header file B.h */
#ifndef __B_H
#define __B_H

class A;

class B
{
public:
    B(A &_objA);

        // reference
        A &objA;
};
#endif /* __B_H */

最后,只需在每个实现文件中包含标头即可。由于A.h包括B.h,你真的只需要#include "A.h"。但是,我喜欢明确并将它们包括在内。

/* implementation file A.cpp */
#include "A.h"
#include "B.h"

A::A() : objB(*this)
{
}