使用父类型时重写C++方法
C++ method overriding when using parent type
Heyo,当您将对象作为其父类型进行调用时,我对方法重写的工作方式有点困惑。
这是我的示例代码:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
class A {
public:
A() {
std::cout << "Made A.n";
}
void doThing() {
std::cout << "A did a thing.n";
};
};
class B : public A {
public:
B() {
std::cout << "Made B.n";
}
void doThing() {
std::cout << "B did a thing.n";
};
};
class C : public A {
public:
C() {
std::cout << "Made C.n";
}
void doThing() {
std::cout << "C did a thing.n";
};
};
int main(int argc, char** argv) {
std::cout << "n";
std::cout << "Make objects: n";
A a;
B b;
C c;
std::cout << "Call objects normally: n";
a.doThing();
b.doThing();
c.doThing();
std::cout << "Call objects as their parent type from a vector: n";
vector<A> vect;
vect.push_back(a); vect.push_back(b); vect.push_back(c);
for(int i=0;i<vect.size();i++)
vect.data()[i].doThing();
return 0;
}
这是我得到的输出:
Make objects:
Made A.
Made A.
Made B.
Made A.
Made C.
Call objects normally:
A did a thing.
B did a thing.
C did a thing.
Call objects as their parent type from a vector:
A did a thing.
A did a thing.
A did a thing.
另一种语言(如Java)中的相同代码将产生以下输出:
Make objects:
Made A.
Made B.
Made C.
Call objects normally:
A did a thing.
B did a thing.
C did a thing.
Call objects as their parent type from a vector:
A did a thing.
B did a thing.
C did a thing.
简而言之,我如何在c++中实现第二个输出
每当按值将Derived
对象传递给接受Base
的函数时,就会发生称为"切片"的事情。基本上,只使用Derived
对象的Base
部分。
您需要通过引用或指针传递对象以避免这些问题。例如,声明
f(Base&)
允许传入Derived
对象,即允许您写入
f(Derived)
此外,要启用运行时多态性,函数必须标记为virtual
。默认情况下,Java将所有内容都隐式标记为虚拟。然而,这是C++,你不会为你不使用的东西付费(虚拟函数是一种开销)。
PS:在您的代码中,即使您愿意,也不能使用引用的std::vector
。但是,您可以使用std::reference_wrapper
包装对象,这允许您"模拟"引用的std::vector
:
std::vector<std::reference_wrapper<A>> vect
并使用get
成员函数检索参考
for(int i=0;i<vect.size();i++)
vect[i].get().doThing();
或者,也许更简单,只需使用std::vector<A*>
您需要使用virtual
关键字来启用在子类中覆盖的函数。
好的,下面是发生的事情:生成对象:我认为A很明显。构建A对象,其默认构造函数打印
Made A
当您首先实例化一个B对象时,它的父类将被完全构造。因此,在这种情况下,父类是A,它是用默认构造函数构造的,它打印出
Made A
之后,B类的剩余部分被构造并运行其构造函数,该构造函数打印出
Made B
实例化C 时也会发生同样的事情
调用对象上的函数:这只是一个简单的函数调用,因为你覆盖了每个类中被调用的函数,而不是父函数。
当你创建一个对象的向量时,你会将对象复制到它们中,因为你既不传递引用也不传递指针。您尚未编写复制构造函数,因此将运行默认的逐位复制。通过这种方式,从B类对象中得到一个a类对象,函数将打印出a做了什么,而不是B做了什么。C.也是如此
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- 在 C++ 中用派生类型重写成员函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 方法重写线程C++中的概念
- 为重写std::exception的库生成swig接口时出错
- 如何强制从重写方法调用重写的方法基方法?
- 用于C++的静态二进制检测或二进制重写工具和框架
- 如何将 if else 语句重写为 switch 语句
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 用 C 重写C++类
- 是否总是可以将使用递归编写的程序重写为不使用递归的程序C++,性能观点是什么?
- 重写虚拟函数和继承
- C++调用使用重写函数的父类函数
- 重写打印函数而不是覆盖基类
- 不允许在类定义之外重写
- C++有没有办法强制重写一组方法,如果其中一个方法在子类中具有重写?
- C++:从抽象类重写纯虚拟运算符重载
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 重写函数不打印基类数据