我有两个类,客户端和主机.当所有的东西都加载时,您可以选择按两个按钮,如果按下按钮1,客户端被加载,并且按下按钮2主机被加载.
现在客户端和主机都是相当大的类,我不想将它们都放在内存中.所以我的想法是创建一个基类,然后客户端和主机应该扩展基类,然后我唯一要做的是这样的:
Base connection; //If button 1 is pressed: connection = Client(); //If button 2 is pressed: connection = Host();
这听起来太好了,不能成真,当我尝试了,我没有错误.现在出现了问题,Base有一个叫做A的函数,而Client有一个叫做B的函数,所以函数B对于类Client是唯一的.
当我尝试调用函数B时,我得到这个错误:’class Base’没有名为’B’的成员.我怎么能让C知道我正在和Client或Host进行通话,而不是Base?我也开放了一个全新的方法来解决这个问题.也许这只是我思维过程中的一个错误.
提前致谢!
解决方法
@H_502_16@ 你遇到了一种我们称之为对象切片的情况,这在C语言中是一个常见的问题.当您将一个子类型的值分配给一个超级类型的新位置(您的可变连接)时,会发生对象分片.这引入了一个新的实例副本,但是超类型的副本,而不是子类型,所以你丢失了你想要实例化的具体类的信息.
为了避免这种情况,您有多个选项.
经典方法使用指针:
Base * connection; connection = new YourConcreteType();
然后,为了使用这个对象,你必须使用星号运算符(*)去掉它:
(*connection).function(); connection->function(); // syntactic sugar,semantically equivalent
不要忘记:使用后必须删除该对象:
delete connection;
为了简化这个,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!
还有其他“智能指针”类型,如unique_ptr,如果您不打算传递指针(如果它保留在范围内),可以使用它.
现在,您可以分别在两个类中实现这些功能.为了使用多态,这意味着,在运行时,调用一个子类或另一个子类的函数,根据构造的子类,应该将基类中的函数声明为虚函数,否则,将调用Base中的函数定义,而不管您构造的具体类型如何.
在你的情况下,你想调用一个应该做不同的功能,这取决于类型.虽然您的方法是引入两个不同的功能,即A和B,您可以只声明一个单一的函数,我们把它称为handleEvent,作为基类中的纯虚拟(=抽象)函数,这意味着“这个函数是在子类中实现“,并在两个子类中独立定义它:
Base { .... virtual void handleEvent(...) = 0; // "= 0" means "pure" }; // Don't provide an implementation
Client { void handleEvent(...); // override it }; // define it for Client: void Client::handleEvent(...) { ... }
Host { void handleEvent(...); // override it }; // define it for Host: void Host::handleEvent(...) { ... }