Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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++ 如何传递子类作为期望基类的函数的参数,然后将该对象传递到指向这些抽象类对象的指针向量中? TL;博士_C++_C++11_Stl - Fatal编程技术网

C++ 如何传递子类作为期望基类的函数的参数,然后将该对象传递到指向这些抽象类对象的指针向量中? TL;博士

C++ 如何传递子类作为期望基类的函数的参数,然后将该对象传递到指向这些抽象类对象的指针向量中? TL;博士,c++,c++11,stl,C++,C++11,Stl,我试图将一个子类传递到一个函数中,该函数期望该子类的基类,然后将该基类的唯一指针存储在第三个完全独立的类的向量中 C++11及更高版本 末端TL;博士 我一共有3节课,然后是我的int main 基本抽象类有一个构造函数和一个虚函数。 基类构造函数已实现,而虚拟函数未实现 第二个类是基类的子类。 它实现自己的构造函数并调用基构造函数。 子类的第二部分是虚拟基类函数的具体实现 然后我有了第三个类,它有自己的构造函数。 第三个类有一个函数,其函数头包含对基类的引用。 然后,该函数尝试将该引用传递给抽

我试图将一个子类传递到一个函数中,该函数期望该子类的基类,然后将该基类的唯一指针存储在第三个完全独立的类的向量中

C++11及更高版本

末端TL;博士 我一共有3节课,然后是我的int main

基本抽象类有一个构造函数和一个虚函数。 基类构造函数已实现,而虚拟函数未实现

第二个类是基类的子类。 它实现自己的构造函数并调用基构造函数。 子类的第二部分是虚拟基类函数的具体实现

然后我有了第三个类,它有自己的构造函数。 第三个类有一个函数,其函数头包含对基类的引用。 然后,该函数尝试将该引用传递给抽象类,然后将该引用推回到该抽象类的std::unique_ptr向量中。 因为我不能直接拥有抽象类实例的向量

我的问题是,我目前无法获得此代码的版本进行编译

我一直在网上参考一些资源,试图解决我的问题

pass unique_ptr as an object
https://stackoverflow.com/questions/8114276/how-do-i-pass-a-unique-ptr-argument-to-a-constructor-or-a-function

adding elements of a vector of a base class
https://stackoverflow.com/questions/31410858/adding-elements-to-stdvector-of-an-abstract-class

can't access derived class method from pointer of base class - not entirely relavent, but good knowledge
https://stackoverflow.com/questions/23489554/cant-access-derived-class-method-from-pointer-of-type-base-class

我在一个C++编译的可执行文件中创建了一个未编译的短版本。 文件如下:

/* 这个脚本演示了我在尝试传递子类对象时遇到的困境 作为期望基类的函数的参数,然后 获取函数中传入的对象,并将其添加到该对象的向量中 在一个完全不同的班级。 */ 包括 包括 包括 类基类 { 公众: Baseclasint i { lala=i; } //子类必须实现此方法。 虚拟int addmeint d=0; 受保护的: 内特拉; }; 类子类:基类 { 公众: 子类d,int l:Baseclassd { blahblah=l; } int addmeint d { 返回blahblah+lala+d; } 受保护的: 内布拉布拉赫; }; 类主类 { 公众: 主课 { 另一个=废话; } //这是我似乎无法实现的功能。 //如何使函数参数成为抽象类? //传入的对象不是抽象的。。。 bool addControllerBaseclass&basecont { //这里的这一行不可编译!! //controllers.push_backsd::make_uniquebasecont; 返回true; } 受保护的: 另一个; 矢量控制器; }; int main argc,字符**argv { //创建子类控制器 cont1子类=12、23子类; cont2子类=233子类,2; //创建主对象 Mainclass mainbro=Mainclass23; //将子类控制器添加到主类 //这两行代码无法编译!! //mainbro.addControllercont1; //mainbro.addControllercont2; // 返回0; } 我认为我做了一些非常错误的事情,但我并不觉得我概述的过程本身是不可能的。我只是觉得我在这个问题上做错了

我在脚本中强调了我不确定应该做什么以及代码在哪里中断的地方

我可能需要采取另一种方法来解决这个问题,我只是不知道我有什么选择。

包括 包括 包括 类基类 { 公众: Baseclasint i { lala=i; } //子类必须实现此方法。 虚拟int addmeint d=0; 受保护的: 内特拉; }; 类子类:公共基类 { 公众: 子类d,int l:Baseclassd { blahblah=l; } int addmeint d { 返回blahblah+lala+d; } 受保护的: 内布拉布拉赫; }; 类主类 { 公众: 主课 { 另一个=废话; } //否则,您需要将函数设置为模板 //您将切掉子类的顶部,并且错误地 //复制一个你不能做的基类, //因为基类是纯虚拟的 样板 bool addControllerT和basecont { //不要推回新的独特的PTR,而是重新安置! controllers.emplace_backnew Tbasecont; 返回true; } 受保护的: 另一个; 矢量控制器; }; int main argc,字符**argv { //创建子类控制器 cont1子类=12、23子类; cont2子类=233子类,2; //创建主对象 Mainclass mainbro=Mainclass23; //值得指出的是 方法将获取新的 //cont1和cont2我们不希望mainbro实例删除 //cont1和cont2的内存,因为它们是堆栈分配的 mainbro.addControllercont1; mainbro.addControllercont2; // 返回0; } 包括 包括 包括 类基类 { 公众: Baseclasint i { lala=i; } //子类必须实现此方法。 虚拟int addmeint d=0; 受保护的: 内特拉; }; 类子类:公共基类 { 公众: 子类d,int l:Baseclassd { blahblah=l; } int addmeint d { 返回blahblah+lala+d; } 受保护的: 内布拉布拉赫; }; 类主类 { 公众: 主课 { 另一个=废话; } //否则,您需要将函数设置为模板 //您将切掉子类的顶部,并且错误地 //复制一个你不能做的基类, //因为基类是纯虚拟的 样板 bool addControllerT和basecont { //不要推回新的独特的PTR,而是重新安置! controllers.emplace_backnew Tbasecont; 返回true; } 受保护的: 另一个; 矢量控制器; }; int main argc,字符**argv { //创建子类控制器 cont1子类=12、23子类; cont2子类=233子类,2; //创建主对象 Mainclass mainbro=Mainclass23; //值得指出的是,这些方法将对 //cont1和cont2我们不希望mainbro实例删除 //cont1和cont2的内存,因为它们是堆栈分配的 mainbro.addControllercont1; mainbro.addControllercont2; // 返回0; }
无论何时对虚拟方法使用基指针或引用,请始终添加虚拟析构函数:

    virtual ~Baseclass() = default;
这可以防止在删除基指针时出现未定义的行为

下一位,使用公共继承允许编译器从unique_ptr隐式向上转换为unique_ptr:

类子类:公共基类 你的最后一个问题是所有权问题。通过拥有一个unique_ptr向量,您可以说您的类拥有所有这些对象。但是通过在main中的堆栈上声明它们,您就意味着main拥有它们。相反,在主例程中使用make_unique,并使用std::move:

bool addControllerstd::unique\u ptr basecont { controllers.push_backsd::movebasecont; 返回true; }

auto cont1=std::make_unique12,23; auto cont2=std::make_unique233,2; //创建主对象 Mainclass mainbro=Mainclass23; mainbro.addControllerstd::movecont1; mainbro.addControllerstd::movecont2; 总而言之:

包括 包括 包括 类基类 { 公众: Baseclasint i { lala=i; } virtual~Baseclass=默认值; //子类必须实现此方法。 虚拟int addmeint d=0; 受保护的: 内特拉; }; 类子类:公共基类 { 公众: 子类d,int l:Baseclassd { blahblah=l; } int addmeint d { 返回blahblah+lala+d; } 受保护的: 内布拉布拉赫; }; 类主类 { 公众: 主课 { 另一个=废话; } bool addControllerstd::unique\u ptr basecont { controllers.push_backsd::movebasecont; 返回true; } 受保护的: 另一个; 矢量控制器; }; int main argc,字符**argv { //创建子类控制器 auto cont1=std::make_unique12,23; auto cont2=std::make_unique233,2; //创建主对象 Mainclass mainbro=Mainclass23; mainbro.addControllerstd::movecont1; mainbro.addControllerstd::movecont2; 返回0; }
演示:

无论何时在虚拟方法中使用基指针或引用,请始终添加虚拟析构函数:

    virtual ~Baseclass() = default;
这可以防止在删除基指针时出现未定义的行为

下一位,使用公共继承允许编译器从unique_ptr隐式向上转换为unique_ptr:

类子类:公共基类 你的最后一个问题是所有权问题。通过拥有一个unique_ptr向量,您可以说您的类拥有所有这些对象。但是通过在main中的堆栈上声明它们,您就意味着main拥有它们。相反,在主例程中使用make_unique,并使用std::move:

bool addControllerstd::unique\u ptr basecont { controllers.push_backsd::movebasecont; 返回true; }

auto cont1=std::make_unique12,23; auto cont2=std::make_unique233,2; //c 创建主对象 Mainclass mainbro=Mainclass23; mainbro.addControllerstd::movecont1; mainbro.addControllerstd::movecont2; 总而言之:

包括 包括 包括 类基类 { 公众: Baseclasint i { lala=i; } virtual~Baseclass=默认值; //子类必须实现此方法。 虚拟int addmeint d=0; 受保护的: 内特拉; }; 类子类:公共基类 { 公众: 子类d,int l:Baseclassd { blahblah=l; } int addmeint d { 返回blahblah+lala+d; } 受保护的: 内布拉布拉赫; }; 类主类 { 公众: 主课 { 另一个=废话; } bool addControllerstd::unique\u ptr basecont { controllers.push_backsd::movebasecont; 返回true; } 受保护的: 另一个; 矢量控制器; }; int main argc,字符**argv { //创建子类控制器 auto cont1=std::make_unique12,23; auto cont2=std::make_unique233,2; //创建主对象 Mainclass mainbro=Mainclass23; mainbro.addControllerstd::movecont1; mainbro.addControllerstd::movecont2; 返回0; }
演示:

我看到了修复代码的不同方法,具有不同的含义

存储指针拥有主对象的所有权

class Mainclass
{
public:

    void addController(Baseclass& basecont)
    {
        controllers.push_back(&basecont);
    }

protected:
    std::vector<Baseclass*> controllers;
};
存储副本

class Mainclass
{
public:

    void addController(Baseclass& basecont)
    {
        controllers.push_back(basecont.clone());
    }

protected:
    std::vector<std::unique_ptr<Baseclass>> controllers;
};


我看到了修复代码的不同方法,具有不同的含义

存储指针拥有主对象的所有权

class Mainclass
{
public:

    void addController(Baseclass& basecont)
    {
        controllers.push_back(&basecont);
    }

protected:
    std::vector<Baseclass*> controllers;
};
存储副本

class Mainclass
{
public:

    void addController(Baseclass& basecont)
    {
        controllers.push_back(basecont.clone());
    }

protected:
    std::vector<std::unique_ptr<Baseclass>> controllers;
};


使用bool addControllerstd::unique_ptr basecount并将make_unique对象传递给它。顺便说一句,问题提得很好。错误信息是什么?您能否关注一个错误而不是至少两个错误?使用bool addControllerstd::unique_ptr basecount并将make_unique对象传递给它。顺便说一句,问题提得很好。错误信息是什么?您能关注一个错误而不是至少两个错误吗?只是一个次要问题:解析继承的类对象的类型是在编译时还是在运行时发生的?我想知道上述方法是否会对性能造成超过1~5毫秒的严重影响。换句话说,当我有一个类方法调用存储在唯一\u ptr类型向量中的对象上的方法时,计算是否需要很长时间。虚拟成员按设计在运行时调度请参见:。不过,开销可以忽略不计,与使用函数指针大致相同。在一个强大的现代处理器上,如果你经常调用虚方法,指令缓存很可能会完全消除这一微小的开销。只是一个小问题:解析继承的类对象的类型是在编译时还是在运行时发生的?我想知道上述方法是否会对性能造成超过1~5毫秒的严重影响。换句话说,当我有一个类方法调用存储在唯一\u ptr类型向量中的对象上的方法时,计算是否需要很长时间。虚拟成员按设计在运行时调度请参见:。不过,开销可以忽略不计,与使用函数指针大致相同。在一个强大的现代处理器上,如果你经常调用虚方法,指令缓存可能会完全消除这一微小的开销。