自动引用会话继承

时间:2015-12-16 08:00:20

标签: c++ inheritance

我尝试了解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;
}

1 个答案:

答案 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