C++ 运行时使用继承的代码选择器
有没有办法在容器中插入抽象类?否。C++ 运行时使用继承的代码选择器,c++,inheritance,C++,Inheritance,有没有办法在容器中插入抽象类?否。 基类是否有访问派生类的方法?使用虚拟函数。 有没有办法让这个示例代码正常工作并让控制台发出吠声? vector容器是否有办法保存实例而不是引用/指针 只有在使用实例的引用计数器(这是我最后的选择)时,在std::vector中存储指针才是安全的。我错过什么了吗 class CAnimal { public: virtual void soundsLike() { cout<<"Base function\n";
基类是否有访问派生类的方法?使用虚拟函数。
有没有办法让这个示例代码正常工作并让控制台发出吠声?
vector
容器是否有办法保存实例而不是引用/指针
只有在使用实例的引用计数器(这是我最后的选择)时,在std::vector
中存储指针才是安全的。我错过什么了吗
class CAnimal
{
public:
virtual void soundsLike()
{
cout<<"Base function\n";
}
};
class CDog: public CAnimal
{
public:
void soundsLike()
{
cout<<"Woof\n";
}
};
class CZoo
{
public:
std::vector<CAnimal> animalList;
void addDog()
{
animalList.push_back(CDog());
}
};
有没有办法在容器中插入抽象类 不可以。但是可以插入指向抽象类的指针(最好是智能指针) 有没有一种方法可以让这个示例代码正常工作并让控制台发出声音 除非你愿意带着指针走,否则,你的代码就是吠叫 向量容器是否有办法保留实例而不是引用/指针 可以在容器中保留指针,但不能保留引用。然而,一旦在类中有一个指向您分配的对象的指针或整个指针向量,代码的复杂性就会增加,因为您必须遵循 只有在使用实例的引用计数器(这是我最后的选择)时,在
std::vector
中存储指针才是安全的。我错过什么了吗
class CAnimal
{
public:
virtual void soundsLike()
{
cout<<"Base function\n";
}
};
class CDog: public CAnimal
{
public:
void soundsLike()
{
cout<<"Woof\n";
}
};
class CZoo
{
public:
std::vector<CAnimal> animalList;
void addDog()
{
animalList.push_back(CDog());
}
};
是-看起来你失踪了,这对你来说并不重要。您为此付出的小代价是必须使用std::shared_ptr
来代替CZoo
中所有动物的简单指针
有没有办法在容器中插入抽象类 不可以。但是可以插入指向抽象类的指针(最好是智能指针) 有没有一种方法可以让这个示例代码正常工作并让控制台发出声音 除非你愿意带着指针走,否则,你的代码就是吠叫 向量容器是否有办法保留实例而不是引用/指针 可以在容器中保留指针,但不能保留引用。然而,一旦在类中有一个指向您分配的对象的指针或整个指针向量,代码的复杂性就会增加,因为您必须遵循 只有在使用实例的引用计数器(这是我最后的选择)时,在
std::vector
中存储指针才是安全的。我错过什么了吗
class CAnimal
{
public:
virtual void soundsLike()
{
cout<<"Base function\n";
}
};
class CDog: public CAnimal
{
public:
void soundsLike()
{
cout<<"Woof\n";
}
};
class CZoo
{
public:
std::vector<CAnimal> animalList;
void addDog()
{
animalList.push_back(CDog());
}
};
是-看起来你失踪了,这对你来说并不重要。你为此付出的代价很小,那就是必须使用std::shared_ptr
来代替你可以使用的CZoo中所有动物的简单指针
std::vectorzoo;
zoo.push_back(新的CDog());
zoo[0]->soundsLike();
坏吗?unique_ptr将为您处理销毁
我认为你不能使用参考资料。我也不认为你能让它“吠叫”目前。只有“汪”声。你可以用
std::vectorzoo;
zoo.push_back(新的CDog());
zoo[0]->soundsLike();
坏吗?unique_ptr将为您处理销毁
我认为你不能使用参考资料。我也不认为你能让它“吠叫”目前。只有“汪汪”声。问题在于,animalList只是一个基类动物对象的向量。因此,编译器只保留了足够的存储空间来保存CANIAL对象。由于虚拟函数的工作方式,由于查找表的要求,派生的CDog类总是需要比CANIAL类更多的存储空间
由于您的CDog类没有分配足够的存储空间,对象的CDog部分将被切掉,只剩下对象的CAnimal部分
使用指针传递对象是首选的,因为对象的地址总是有相同的存储要求,所以不会遇到任何对象切片问题。问题在于animalList只是基类CAnimal对象的向量。因此,编译器只保留了足够的存储空间来保存CANIAL对象。由于虚拟函数的工作方式,由于查找表的要求,派生的CDog类总是需要比CANIAL类更多的存储空间
由于您的CDog类没有分配足够的存储空间,对象的CDog部分将被切掉,只剩下对象的CAnimal部分
使用指针传递对象是首选的,因为对象的地址总是有相同的存储要求,所以您不会遇到任何对象切片问题。如果您真的想跳过在容器中存储指针,下面是一个实现“伪虚拟”机制的解决方案。请注意,只有在拥有C++11编译器的情况下,这才有效。您需要通过助手函数(caller
)调用虚拟方法,并使用一个方法(makeNoice
,在我们的例子中)作为虚拟方法,通过该机制引导所有虚拟调用
#include <iostream>
#include <vector>
#include <functional>
#include <utility>
// forward declarations of the base class and a helper function
class CAnimal;
void caller(CAnimal* a);
// base class with small extensions
struct CAnimal {
CAnimal() { mf = std::bind(caller, this); }
virtual void soundsLike() { std::cout<<"Base function\n"; }
// this will act as a virtual function
void makeNoice() { mf(this); }
std::function<void (CAnimal*)> mf;
};
// a helper function to call the real virtual function
void caller(CAnimal* a) {a->soundsLike();}
// the actual animals
struct CDog: public CAnimal {
virtual void soundsLike() { std::cout<<"Woof\n"; }
};
struct CCat: public CAnimal {
virtual void soundsLike() { std::cout<<"Miau\n"; }
};
int main()
{
CDog dog;
CCat cat;
std::vector<CAnimal> animalList;
animalList.push_back(dog);
animalList.push_back(cat);
// calling the fake virtual
animalList[0].makeNoice();
animalList[1].makeNoice();
}
#包括
#包括
#包括
#包括
//基类和辅助函数的前向声明
犬类;
无效调用方(CAnimal*a);
//具有小扩展的基类
犬结构{
CAnimal(){mf=std::bind(调用者,this);}
virtual void soundsLike(){std::cout如果您真的想跳过在容器中存储指针,下面是一个实现“伪虚拟”机制的解决方案。请注意,只有当您拥有C++11编译器时,这才有效。您需要通过帮助函数(调用方
)调用虚拟方法,并使用一种方法(makeNoice
,在我们的案例中),该方法充当虚拟的角色,通过该机制传递所有虚拟调用
#include <iostream>
#include <vector>
#include <functional>
#include <utility>
// forward declarations of the base class and a helper function
class CAnimal;
void caller(CAnimal* a);
// base class with small extensions
struct CAnimal {
CAnimal() { mf = std::bind(caller, this); }
virtual void soundsLike() { std::cout<<"Base function\n"; }
// this will act as a virtual function
void makeNoice() { mf(this); }
std::function<void (CAnimal*)> mf;
};
// a helper function to call the real virtual function
void caller(CAnimal* a) {a->soundsLike();}
// the actual animals
struct CDog: public CAnimal {
virtual void soundsLike() { std::cout<<"Woof\n"; }
};
struct CCat: public CAnimal {
virtual void soundsLike() { std::cout<<"Miau\n"; }
};
int main()
{
CDog dog;
CCat cat;
std::vector<CAnimal> animalList;
animalList.push_back(dog);
animalList.push_back(cat);
// calling the fake virtual
animalList[0].makeNoice();
animalList[1].makeNoice();
}
#包括
#包括
#包括
#包括
//基类和辅助函数的前向声明
犬类;
空钙