C++ 从派生类c+中获取变量+;
我希望仅当类是特定的派生类时才执行某些操作。就是我有:C++ 从派生类c+中获取变量+;,c++,class,oop,derived,C++,Class,Oop,Derived,我希望仅当类是特定的派生类时才执行某些操作。就是我有: class X{ int id; } class A: public X{ void run(); } class B: public X{ int lala; } 我想做一些事情,大致如下: main(){ vector<X *> types; types.push_back(new A); types.push_back(new B); int var = 0;
class X{
int id;
}
class A: public X{
void run();
}
class B: public X{
int lala;
}
我想做一些事情,大致如下:
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for(int i = 0; i<types.size(); i++){
if(types[i].isType(A)) {types[i].run();}
}
for(int i = 0; i<types.size(); i++){
if(types[i].isType(B)) {var = lala;}
}
}
<>但我不确定C++中我的选择是什么。
谢谢您可以使用
dynamic\u cast
检查基类指针是否可转换为派生实例
另一种选择是使用一个虚拟函数返回类的typeinfo
,从而使用该信息将指针强制转换为可转换类型。这可能会更有效,具体取决于dynamic\u cast
的实现方式。因此,如果您想尝试看看这种方法在您的平台上是否更快,您可以使用它
正如@Jarod42所指出的,您需要一个虚拟函数,在本例中是析构函数,以便dynamic\u cast
工作。此外,您只需要一个虚拟析构函数,以避免删除实例时出现未定义的行为
范例
#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
struct A {
virtual ~A() {
}
virtual const std::type_info& getTypeInfo() const {
return typeid(A);
}
};
struct B : public A {
virtual const std::type_info& getTypeInfo() const override {
return typeid(B);
}
};
struct C : public A {
virtual const std::type_info& getTypeInfo() const override {
return typeid(C);
}
};
int main()
{
std::vector<A*> data;
data.push_back(new A);
data.push_back(new B);
data.push_back(new C);
for (auto& val : data) {
if (val->getTypeInfo() == typeid(A)) {
std::cout << "A";
}
else if (val->getTypeInfo() == typeid(B)) {
std::cout << "B";
}
else if (val->getTypeInfo() == typeid(C)) {
std::cout << "C";
}
std::cout << std::endl;
}
for (auto& val : data) {
delete val;
}
}
#包括
#包括
#包括
#包括
结构A{
虚拟~A(){
}
虚拟常量std::type_info&getTypeInfo()常量{
返回类型ID(A);
}
};
结构B:公共A{
虚拟常量std::type_info&getTypeInfo()常量重写{
返回类型ID(B);
}
};
结构C:公共A{
虚拟常量std::type_info&getTypeInfo()常量重写{
返回类型ID(C);
}
};
int main()
{
std::矢量数据;
数据。推回(新A);
数据。推回(新B);
数据。推回(新C);
用于(自动和val:数据){
如果(val->getTypeInfo()==typeid(A)){
std::cout getTypeInfo()==typeid(B)){
std::cout getTypeInfo()==typeid(C)){
std::cout您正在寻找的
#包括
使用名称空间std;
X类{
公众:
int-id;
virtual~X()=默认值;
};
A类:公共X{
公众:
无效运行(){}
};
B类:公共X{
公众:
内特拉;
};
main(){
媒介类型;
类型。推回(新A);
类型。推回(新B);
int-var=0;
对于(inti=0;i这个问题的现代C++17解决方案是使用变量向量,即std::vector我有两个想法
为什么不使用一个共享方法来返回一个值,该值给出了它是a还是B的上下文?例如,如果lala只返回0或更大的值,那么可以使用void run()代替int run()并始终返回-1
class X {
int id;
virtual int run() = 0; //Assuming X isn't meant to be instantiated
}
class A: public X {
// Return -1 to differentiate between As and Bs
int run() { return -1; }
}
class B: public X {
int lala;
int run() { return lala;}
}
那么你有
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0, temp = 0;
for( int i = 0; i<types.size(); i++ ) {
if( (temp = types[i].run()) != -1 )
var = temp;
....
}
}
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for( int i = 0; i<types.size(); i++ ) {
if( types[i].isA == true ) {
types[i].run();
}
else {
var = types[i].lala;
}
}
那么你有
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0, temp = 0;
for( int i = 0; i<types.size(); i++ ) {
if( (temp = types[i].run()) != -1 )
var = temp;
....
}
}
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for( int i = 0; i<types.size(); i++ ) {
if( types[i].isA == true ) {
types[i].run();
}
else {
var = types[i].lala;
}
}
main(){
媒介类型;
类型。推回(新A);
类型。推回(新B);
int-var=0;
对于(int i=0;idynamic\u cast
需要至少一个虚拟方法(作为析构函数)。“这通常比dynamic\u cast
性能更好。”-为什么编译器要实现一些功能完全相同但速度较慢的东西?请引用一个源代码。getTypeInfo
的定义可能会被复制粘贴到所有地方。在这里必须非常小心。您仍然必须以某种方式强制转换它以访问其成员。您可以使用static\u cast
这不会带来任何开销,除非您由于多重继承而需要横向转换。那么您无论如何都必须使用dynamic\u cast
。这也回答了@ChristianHackl的问题-编译器必须为dynamic\u cast
做一些更聪明的事情来支持横向转换。我可能应该尽量避免这样做泛化:PSoX
只是为了让它们保持在同一个向量中?修复漏洞不会有什么坏处。谢谢Goran。我想还有一个小问题是,如果a和B都有派生类,那么相同的if语句会对派生类起作用吗。也就是说,如果C是从a派生的,我们用“if(auto ta=dynamic_cast(types[i])”会返回真值吗?@ChristianHackl我知道,我想更改最小的codo量以使其可编译-问题不是泄漏:)但是我会添加带有固定漏洞的代码以供参考。@Davelas是的,如果C
是从A
派生的,它也会起作用,并且它将通过A
的路径。请注意,@Rabster的解决方案并非如此。我还想指出,过度使用dynamic\u cast
通常是糟糕的代码设计的标志。我不知道这是一个精确的应用程序,但是如果您试图对一组对象执行操作,这取决于对象的运行时类型,那么您可能正在寻找访问者设计模式:这是解决此问题的一个很好的解决方案(并且比dynamic\u cast
变体的性能更好),但我只想指出,如果我们向层次结构中添加新类,并且希望在类型中也添加它们,那么它将不再有效,除非我们更改向量的签名。
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0, temp = 0;
for( int i = 0; i<types.size(); i++ ) {
if( (temp = types[i].run()) != -1 )
var = temp;
....
}
}
class X {
int id;
bool isA;
}
class A: public X {
A() : isA(true) { };
void run();
}
class B: public X {
B() : isA(false) { } ;
int lala;
}
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for( int i = 0; i<types.size(); i++ ) {
if( types[i].isA == true ) {
types[i].run();
}
else {
var = types[i].lala;
}
}