微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C:将父类转换为子类

我对C很新,这是我遇到的问题:
我有两个类,客户端和主机.当所有的东西都加载时,您可以选择按两个按钮,如果按下按钮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?我也开放了一个全新的方法解决这个问题.也许这只是我思维过程中的一个错误.

提前致谢!

解决方法

你遇到了一种我们称之为对象切片的情况,这在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(...) {
    ...
}

原文地址:https://www.jb51.cc/c/112829.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐