Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.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++可以通过引用传递一个类吗?_C++_Reference - Fatal编程技术网

C++可以通过引用传递一个类吗?

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

尝试将父类对象传递给子类对象,以便子类对象可以控制父类对象的方法

但是,这会导致与标题相关的问题。 我试着向前声明其中一个类,但似乎无论先声明什么类,都无法读取下面声明的类

这两个错误都指向设备的构造函数,试图调用dm的hello world方法,它们是:

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) {}
};