我尝试了解OOP中的继承。所以,我已经尝试了一些尝试。但是,有两点我坚持认为其中一个是object slicing
。另一个是调用析构函数的顺序。为什么Box {carton}
需要正确的复制文件?如果添加Box {carton}
,如何将纸箱类型转换为Box类型(我绝对不理解它)。
// right ctor
/*
Carton(const Carton& carton) : Box {carton}, material {carton.material}
{ std::cout << "Carton copy constructor" << std::endl; }
*/
代码:
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
class Box
{
protected:
double length;
double width;
double height;
public:
// Constructors
Box(double lv, double wv, double hv);
Box(double side) : Box {side, side, side}
{ std::cout << "Box(double) called.\n"; }
Box() { std::cout << "Box() called.\n"; }
double volume() const
{ return length * width * height; }
double getLength() const { return length; }
double getWidth() const { return width; }
double getHeight() const { return height; }
~Box()
{ cout << "box destructor" << endl; }
void print();
// copy ctor
Box(const Box& box) : length{box.length}, width{box.width}, height{box.height}
{ std::cout << "Box copy constructor" << std::endl; }
};
class Carton : public Box
{
private:
string material {"Cardboard"};
public:
Carton(double lv, double wv, double hv, const string desc) : Box {lv, wv, hv}, material {desc}
{ std::cout << "Carton(double,double,double,string) called.\n";}
Carton(const string desc) : material {desc}
{ std::cout << "Carton(string) called.\n";}
Carton(double side, const string desc) : Box::Box(side),material {desc}
{ std::cout << "Carton(double,string) called.\n";}
Carton() { std::cout << "Carton() called.\n";}
~Carton()
{ cout << "cartoon destructor" << endl; }
void print();
// right ctor
/*
Carton(const Carton& carton) : Box {carton}, material {carton.material}
{ std::cout << "Carton copy constructor" << std::endl; }
*/
Carton(const Carton& carton) : material {carton.material}
{ std::cout << "Carton copy constructor" << std::endl; }
};
int main()
{
// Declare and initialize a Carton object
Carton carton(20.0, 30.0, 40.0, "Glassine board");
Carton cartonCopy(carton); // Use copy constructor
}
// Ctor
Box::Box(double lv, double wv, double hv) : length {lv}, width {wv}, height {hv}
{ std::cout << "Box(double, double, double) called.\n"; }
// Redefinitions
void Box::print()
{
cout << "Box printttttt" << endl;
}
void Carton::print()
{
cout << "Carton printttttt" << endl;
}
答案 0 :(得分:0)
请记住,继承是一种“是一种”关系。 Carton
是 Box
,这就是为什么在Carton
出现时可以使用Box
的原因。
但请注意object slicing问题。如果函数按值获取Box
参数,并且传递Carton
对象,则该函数将仅获取Box
部分。
此外,您还有另一个问题,即print
功能不是virtual
。这意味着即使您有指向Box
的指针或引用并传递Carton
,也不会调用Carton::print
函数。
让我们用一个例子来说明这一点:
void foo(Box const& box)
{
box.print();
}
int main()
{
Carton carton(...);
foo(carton);
}
上面的示例代码不会有任何对象切片问题,因为foo
函数会获得基类的引用。但是,它会打印
Box printttttt
如果你Box::print
虚拟
virtual void print();
然后上面的代码将打印
Carton printttttt