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

Pass instance of an object to member during initialization using *this

本文关键字:实例 对象 成员 this 初始化      更新时间:2023-10-16

在传递类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;
}

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

try following Pass 'this'对象到初始化列表以供引用。这只是一个链接问题吗?

这行不通。A包含一个B实例,B包含一个A实例。由于它们是递归定义的,因此无法构造这两种类型的对象。

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

正如其他人所说,在使用A之前没有定义它。但是,您可以使用a的前向声明来允许B包含对a的引用。在B的类定义中,它仍然是一个不完整的类型,但是您可以将B的构造函数移到类定义之外。类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头文件中的forward声明:

/* 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)
{
}