C++可以通过引用传递一个类吗?
尝试将父类对象传递给子类对象,以便子类对象可以控制父类对象的方法 但是,这会导致与标题相关的问题。 我试着向前声明其中一个类,但似乎无论先声明什么类,都无法读取下面声明的类 这两个错误都指向设备的构造函数,试图调用dm的hello world方法,它们是:C++可以通过引用传递一个类吗?,c++,reference,C++,Reference,尝试将父类对象传递给子类对象,以便子类对象可以控制父类对象的方法 但是,这会导致与标题相关的问题。 我试着向前声明其中一个类,但似乎无论先声明什么类,都无法读取下面声明的类 这两个错误都指向设备的构造函数,试图调用dm的hello world方法,它们是: Use of undefined type 'DeviceManager' Left of '->HelloWorld' must point to class/struct/union/generic type class De
Use of undefined type 'DeviceManager'
Left of '->HelloWorld' must point to class/struct/union/generic type
class DeviceManager;
class Device
{
public:
Device(DeviceManager* manager)
{
dm = 0;
this->dm = manager;
this->dm->HelloWorld();
}
DeviceManager* dm;
};
//device manager
class DeviceManager
{
public:
DeviceManager()
{
p = 0;
}
void HelloWorld()
{
//if this calls we know the child has control over the parent.
cout << "Hello World";
}
Device* p;
};
对
要解决具有类成员和函数声明的循环依赖关系,可以向前声明类:
class A;
class B {
A *a;
};
class A {
B *b;
};
要定义访问其他类成员的类成员函数,必须在定义其他类后定义该函数:
class B;
class A {
public:
void f(B &arg);
};
class B {
public:
void g(A &arg);
};
void A::f(B &arg) {
arg.g(*this);
}
void B::g(A &arg) {
arg.f(*this);
}
通常,在C++项目中,您甚至不会遇到这样的问题:将函数定义(即实现)放入.CPP文件中,同时将类定义放入头文件中。类转发声明(如果必要)可以放入它们自己的头文件中,所有需要它们的头文件都包含这些头文件
关于如何将上述代码拆分为多个文件的完整示例: a、 cpp b、 cpp a、 h b、 h 转发声明 一般来说,如果您需要向前声明一个类,您可能设计了一些错误的东西,应该考虑是否有更好的方法,但也有完全有效的用例需要类向前声明 如果您不理解我的ifndef,请定义和endif预处理器行:这些是头保护,应该与其他地方包含的所有文件一起使用,除非您确切地知道自己在做什么。相信我。你会后悔错过的。是的 要解决具有类成员和函数声明的循环依赖关系,可以向前声明类:class A;
class B {
A *a;
};
class A {
B *b;
};
要定义访问其他类成员的类成员函数,必须在定义其他类后定义该函数:
class B;
class A {
public:
void f(B &arg);
};
class B {
public:
void g(A &arg);
};
void A::f(B &arg) {
arg.g(*this);
}
void B::g(A &arg) {
arg.f(*this);
}
通常,在C++项目中,您甚至不会遇到这样的问题:将函数定义(即实现)放入.CPP文件中,同时将类定义放入头文件中。类转发声明(如果必要)可以放入它们自己的头文件中,所有需要它们的头文件都包含这些头文件
关于如何将上述代码拆分为多个文件的完整示例: a、 cpp b、 cpp a、 h b、 h 转发声明 一般来说,如果您需要向前声明一个类,您可能设计了一些错误的东西,应该考虑是否有更好的方法,但也有完全有效的用例需要类向前声明如果您不理解我的ifndef,请定义和endif预处理器行:这些是头保护,应该与其他地方包含的所有文件一起使用,除非您确切地知道自己在做什么。相信我。如果您的问题是循环依赖性,您会后悔使用它。,如下所示:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
您可以通过向前声明一个类并通过指针传递对象来解决这个问题
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};
如果您的问题是循环依赖性,如下所示:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
您可以通过向前声明一个类并通过指针传递对象来解决这个问题
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};
通过引用传递自己到什么?你能分享一些代码来说明你的问题吗?到目前为止,您的问题还不清楚,因为它感觉好像对引用的存在提出了质疑。请向我们展示给您带来麻烦的代码。对象将自身作为引用传递是完全可以接受的。提供了一些代码,希望现在一切都有意义。确保您知道您在这里做什么。不实现设备::~设备显然会导致内存泄漏,不实现拷贝构造函数,或者不知道为什么要这样做,都会毁了你的一天。在C++11中,应该将dm设置为nullptr,而不是0。在C++的早期版本中,应该将其设置为NULL。在C++11中,您可能还应该使用std::unique_ptr,这将避免上述陷阱。嘿,麦克,谢谢:我确实使用unique_ptr,并且在实际程序中有解构器,您是对的,我从来没有完全理解我们为什么使用复制构造函数。通过引用传递它自己到什么?你能分享一些代码来说明你的问题吗?到目前为止,您的问题还不清楚,因为它感觉好像对引用的存在提出了质疑。请向我们展示给您带来麻烦的代码。对象将自身作为引用传递是完全可以接受的。提供了一些代码,希望现在一切都有意义。确保您知道您在这里做什么。不实现设备::~设备显然会导致内存泄漏,不实现拷贝构造函数,或者不知道为什么要这样做,都会毁了你的一天。在C++11中,应该将dm设置为nullptr,而不是0。在C++的早期版本中,应该将其设置为NULL。
在C++11中,您可能还应该使用std::unique_ptr,这将避免上述陷阱。嘿,麦克,谢谢:我确实使用unique_ptr,并且在实际程序中有解构器,您是对的,我从来没有完全理解我们为什么使用复制构造函数。您确定您理解OP想要问的问题吗?与其猜测,不如要求澄清。。。例如,我无法理解您在示例中谈论的是什么循环依赖。你的代码中根本没有循环。OP在提到他的“包含路径创建无限循环”时最有可能谈论的是循环头依赖,这是由两个类定义引起的,需要其他类声明,我不知道OP想问什么。我会等待澄清。你确定你明白OP想要问什么吗?与其猜测,不如要求澄清。。。例如,我无法理解您在示例中谈论的是什么循环依赖。你的代码中根本没有循环。OP在提到他的“包含路径创建无限循环”时最有可能谈论的是循环头依赖,这是由两个类定义引起的,需要其他类声明,我不知道OP想问什么。我将等待澄清。谢谢!我相信这会有很大帮助:谢谢!我相信这会有很大帮助:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};