tve*_*eeg 10 c++ oop inheritance casting class
我对C++很新,这就是我遇到的问题:我有两个类,Client而且Host.当所有内容都加载后,您可以选择按两个按钮,如果按下按钮1 Client则加载,如果按下按钮2 Host则加载.
现在,这两个Client和Host是相当大的班,我不希望把他们俩到内存中.所以我的想法是创建一个Base类,然后两个Client并且Host应该扩展基类,然后我唯一需要做的就是:
Base connection;
//If button 1 is pressed:
connection = Client();
//If button 2 is pressed:
connection = Host();
Run Code Online (Sandbox Code Playgroud)
这听起来好得令人难以置信,当我尝试它时,我没有错.现在出现问题,Base有一个函数调用A,并且Client有一个函数调用B.所以该功能B是该类独有的Client.
当我尝试调用函数时,B我得到了这个错误:'class Base' has no member named 'B'.我怎样才能令C++知道,我说上课Client或Host代替Base?我也对这个问题有了全新的解决方法.也许这只是我思考过程中的一个错误.
提前致谢!
您遇到了一种我们称之为对象切片的情况,这是具有值语义(如C++)的语言中的常见问题.
当您将子类型的值分配给connection超类型的新位置(您的变量)时,会发生对象切片.这引入了实例的新副本,但是超类型而不是子类型,因此您将丢失有关要实例化的具体类的信息.
为避免这种情况,您有多种选择.
在传统方法采用指针:
Base * connection;
connection = new YourConcreteType();
Run Code Online (Sandbox Code Playgroud)
然后,要使用此对象,您必须使用星号运算符()对其进行解除*:
(*connection).function();
connection->function(); // syntactic sugar, semantically equivalent
Run Code Online (Sandbox Code Playgroud)
不要忘记:您必须在使用后删除该对象:
delete connection;
Run Code Online (Sandbox Code Playgroud)
为了简化这一点,C++引入了两个概念:引用和智能指针.虽然前者限制只分配一次,但它在语法上最简单.后者类似于指针方法,但您不必关心删除,因此您不太可能遇到内存泄漏情况:
std::shared_ptr<Base> connection;
connection = make_shared<YourConcreteType>(); // construction via 'make_shared'
// ... use as if it were just a pointer ...
connection->function();
// no delete!
Run Code Online (Sandbox Code Playgroud)
还有其他"智能指针"类型,unique_ptr如果您不打算传递指针(如果它保持在范围内),则可以使用它们.
现在,您可以分别在两个类中实现这些功能.为了利用多态,这意味着,在运行时,要么调用一个子类的函数,要么调用另一个子类的函数,这取决于构造的是哪一个,你应该将基类中的函数声明为virtual,否则,函数Base无论您构造的具体类型如何,都将调用in .
在您的情况下,您希望调用一个应该执行不同操作的函数,具体取决于类型.虽然你的方法是引入两个不同的功能,即A和B,你可以声明一个单一的功能,让我们把它handleEvent作为一个纯虚(=摘要)在基类,这意味着"这个功能在子中实现功能classes",并在两个子类中独立定义:
Base {
....
virtual void handleEvent(...) = 0; // "= 0" means "pure"
};
// Don't provide an implementation
Run Code Online (Sandbox Code Playgroud)
Client {
void handleEvent(...); // override it
};
// define it for Client:
void Client::handleEvent(...) {
...
}
Run Code Online (Sandbox Code Playgroud)
Host {
void handleEvent(...); // override it
};
// define it for Host:
void Host::handleEvent(...) {
...
}
Run Code Online (Sandbox Code Playgroud)