C++;方法参数中的动态绑定 我最近想通过C++的C++来动态地解析一个成员/函数,它的输入参数来自于一些派生版本。我的意思是: #include <iostream> class Base { }; class DerivedA : public Base { }; class DerivedB : public Base { }; class DerivedC : public Base { }; class Test { public: void world( DerivedA *instance ) { std::cout << "DerivedA" << std::endl; } void world( DerivedB *instance ) { std::cout << "DerivedB" << std::endl; } void world( Base *instance ) { std::cout << "Base" << std::endl; } }; int main() { Base *a = new Base; Base *b = new DerivedA; Base *c = new DerivedB; Base *d = new DerivedC; Test hello; hello.world( a ); hello.world( b ); hello.world( c ); hello.world( d ); return 0; }
但可以肯定的是,我真正得到的输出是:C++;方法参数中的动态绑定 我最近想通过C++的C++来动态地解析一个成员/函数,它的输入参数来自于一些派生版本。我的意思是: #include <iostream> class Base { }; class DerivedA : public Base { }; class DerivedB : public Base { }; class DerivedC : public Base { }; class Test { public: void world( DerivedA *instance ) { std::cout << "DerivedA" << std::endl; } void world( DerivedB *instance ) { std::cout << "DerivedB" << std::endl; } void world( Base *instance ) { std::cout << "Base" << std::endl; } }; int main() { Base *a = new Base; Base *b = new DerivedA; Base *c = new DerivedB; Base *d = new DerivedC; Test hello; hello.world( a ); hello.world( b ); hello.world( c ); hello.world( d ); return 0; },c++,rtti,dynamic-binding,C++,Rtti,Dynamic Binding,但可以肯定的是,我真正得到的输出是: Base Base Base Base 我明白,动态绑定是另一种方式,在基类的派生类中解析正确的成员函数,而不是像那样,但是它能以任何方式工作吗 也许我只是错过了要点 不过,我要提前表示感谢 塞巴斯蒂安类型a,b,c和d都是Base*。编译器不跟踪“变量包含的内容”。如果您希望这样做,则需要在派生的类中使用虚拟函数,例如: class Base { public: virtual const char* MyName() { return "Ba
Base
Base
Base
Base
我明白,动态绑定是另一种方式,在基类的派生类中解析正确的成员函数,而不是像那样,但是它能以任何方式工作吗
也许我只是错过了要点
不过,我要提前表示感谢
塞巴斯蒂安类型
a
,b
,c
和d
都是Base*
。编译器不跟踪“变量包含的内容”。如果您希望这样做,则需要在派生的类中使用虚拟函数,例如:
class Base {
public:
virtual const char* MyName() { return "Base"; }
};
class DerivedA : public Base {
public:
virtual const char* MyName() { return "DerivedA"; }
};
... similiar for all derived classes ...
void world( Base *instance )
{
std::cout << instance->MyName() << std::endl;
}
类基{
公众:
虚拟常量char*MyName(){return“Base”;}
};
DerivedA类:公共基础{
公众:
虚拟常量char*MyName(){return“DerivedA”;}
};
... 所有派生类的相似性。。。
虚空世界(基本*实例)
{
std::cout MyName()类型a
、b
、c
和d
都是Base*
。编译器不跟踪“变量包含的内容”。如果这是您想要做的,那么您需要在派生的类中使用虚拟函数,例如:
class Base {
public:
virtual const char* MyName() { return "Base"; }
};
class DerivedA : public Base {
public:
virtual const char* MyName() { return "DerivedA"; }
};
... similiar for all derived classes ...
void world( Base *instance )
{
std::cout << instance->MyName() << std::endl;
}
类基{
公众:
虚拟常量char*MyName(){return“Base”;}
};
DerivedA类:公共基础{
公众:
虚拟常量char*MyName(){return“DerivedA”;}
};
…对于所有派生类都是相似的。。。
虚空世界(基本*实例)
{
std::cout MyName()在您的示例中,您没有运行时多态性方案(即动态绑定)。您拥有的是一个重载成员函数,在重载解析中,编译器正确地选择了void world(Base*instance)
为了得到您想要的,您应该应用如下继承方案:
class Base {
public:
virtual ~Base() {}
virtual void world() const { std::cout << "Base" << std::endl; }
};
class DerivedA : public Base {
public:
virtual ~DerivedA() {}
void world() const { std::cout << "DerivedA" << std::endl; }
};
class DerivedB : public Base {
public:
virtual ~DerivedB() {}
void world() const { std::cout << "DerivedB" << std::endl; }
};
class DerivedC : public Base {
public:
virtual ~DerivedC() {}
using Base::world;
};
不幸的是,重载解析发生在编译时,而动态调度发生在运行时。因此,如果您希望编译器从基
指针推断底层类型,然后从测试
类中选取正确的成员函数,这是不可行的。在您的示例中,您没有这样做拥有一个运行时多态性方案(即动态绑定)。你拥有的是一个重载成员函数,在重载解析中,编译器正确地选择了voidworld(Base*instance)
为了得到您想要的,您应该应用如下继承方案:
class Base {
public:
virtual ~Base() {}
virtual void world() const { std::cout << "Base" << std::endl; }
};
class DerivedA : public Base {
public:
virtual ~DerivedA() {}
void world() const { std::cout << "DerivedA" << std::endl; }
};
class DerivedB : public Base {
public:
virtual ~DerivedB() {}
void world() const { std::cout << "DerivedB" << std::endl; }
};
class DerivedC : public Base {
public:
virtual ~DerivedC() {}
using Base::world;
};
不幸的是,重载解析发生在编译时,而动态调度发生在运行时。因此,如果您希望编译器从Base
指针推断底层类型,然后从Test
类中选取正确的成员函数,这是不可行的。这里的用例是什么不明白为什么不能简单地将每个变量定义为相应的派生类型,而不是Base
。获得所需功能的唯一方法是使用dynamic\u cast
。您正在将Base*
传递给所有这些函数。您需要为您想要实现的功能使用(您必须使world
函数成为成员函数)。@RedAlert:您还需要至少有一个虚拟成员函数,并执行if(dynamic_cast(instance){…}
-这两种方法都可能比最初调用虚拟函数更耗时。首先,这背后的意义是,实例是在其他函数中创建的,但在这里,我希望运行与“测试”不同的代码-类,我无法确定每个对象是哪个类的实例。我知道,我可以像Mats Peterson所说的那样做,但我希望将代码保留在测试类中,而不是对象中。一个解决方案,我现在可以想到(我可能在几小时或几天内想出其他解决方案),是添加一个包装类。让我写下来……这里的用例是什么?我不明白为什么不能简单地将每个变量定义为相应的派生类型,而不是Base
。获得所需功能的唯一方法是使用dynamic\u cast
。您正在将Base*
传递给所有这些函数。哟你需要使用你想要实现的功能(你必须使world
函数成为一个成员函数)。@RedAlert:你还需要至少有一个虚拟成员函数,然后执行if(dynamic_cast(instance){…}
-这两种方法都可能比最初调用虚拟函数更耗时。首先,这背后的意义是,实例是在其他函数中创建的,但在这里,我希望运行与“测试”不同的代码-类,我无法确定每个对象是哪个类的实例。我知道,我可以像Mats Peterson所说的那样做,但我希望将代码保留在测试类中,而不是对象中。一个解决方案,我现在可以想到(我可能在几小时或几天内想出其他解决方案)……我要写一个包装类。让我写这个……在C++中,你不能这样做(至少,不使用<代码>如果(DyrimeCaskCase[..)){…} /Cuth>类型构造,这不是正确的方法。只是简单地使用包装器的方法。也显示C++的限制;不确定我是使用它还是接受它作为一个提示,使用一个更合适的OO设计:-谢谢!有可能更漂亮/更好的解决方案…但是,我在晚上11点半的时候都无法想到,同时试图在我的编译器中获得一个访问者模式来处理我的AST……)在C++中,你不能这么做(好吧,至少不使用if(dynamic_cast(…){。。。
class Test {
public:
void world( DerivedA *instance ) { instance->world(); }
void world( DerivedB *instance ) { instance->world(); }
void world( Base *instance ) { instance->world(); }
};