簡體   English   中英

C ++父類,其中包含在2個不同子類中實現的虛方法

[英]C++ Parent class with virtual methods implemented in 2 different child classes

很難讓標題非常清楚,但我會嘗試解釋上下文(下面有一些代碼)。 注意:我已經看到類似的問題得到了解答,但他們只用1個孩子類來處理這些案例。 所以他們對我的情況並沒有真正的幫助,因為我有2個孩子班。

上下文:我有一個父類Shape,它有2個子元素:Circle和Square。 我將有一個Shape對象的矢量,但這些Shape對象實際上只是Circle對象或Square對象。 我需要Circle和Square類具有相同的父類,以便我可以將它們存儲在同一個向量中。

訣竅是我需要使用向量中的Shape對象來調用Circle類或Square類中實現的方法,因此,我需要在父類Shape中使用這些方法的“虛擬”版本。

這是我的類的代碼的簡化部分:

Shape.h:

class Shape{
public:
    std::string getColor();

    virtual int getRadius() = 0; //Method implemented in Circle
    virtual int getHeight() = 0; //Method implemented in Square
    virtual int getWidth() = 0;  //Method implemented in Square

protected:
    std::string color;
};

class Circle : public Shape{
public:
    int getRadius();

private:
    int radius;
};

class Square : public Shape{
public:
    int getHeight();
    int getWidth();

private:
    int height;
    int width;
};

在Shape.cpp中我有這樣的事情:

std::string Shape::getColor(){
    return color;
}

int Circle::getRadius(){
    return radius;
}

int Square::getHeight(){
    return height;
}

int Square::getWidth(){
    return width;
}

當我想創建Circle和Square對象時,main.cpp中會出現錯誤

Circle *c = new Circle(...);//Error: cannot instantiate abstract class
                            //pure virtual function "Shape::getHeight" has no overrider
                            //pure virtual function "Shape::getWidth" has no overrider


Square *s = new Square(...);//Error: cannot instantiate abstract class
                            //pure virtual function "Shape::getRadius" has no overrider

因此,似乎我需要在Square類中聲明“getRadius”並在Circle類中聲明“getHeight”和“getWidth”...

我嘗試用虛擬添加它們,但這使得Circle和Square抽象類,所以我不能用它們創建任何對象。

有沒有辦法讓這項工作?

這是我在stackoverflow上發布的第一個問題。 我希望一切都清楚。 謝謝您的幫助!

您的虛擬方法並不是虛擬方法的理想選擇,因為它們具有一個類的特定功能,但對另一個類沒有用處。

虛擬方法的好例子是由每個類實現但具有不同功能或結果的東西,如virtual int area()virtual bool intersects( Shape * otherShape )等等。

無論如何,這是你如何編譯你的代碼(有一些額外的):

形狀:

class Shape{
public:
    std::string getColor();

    Shape() {}
    virtual ~Shape() {}

    virtual int getRadius() { return 0; }  // no pure virtual
    virtual int getHeight() { return 0; }  // no pure virtual
    virtual int getWidth() { return 0; }   // no pure virtual

protected:
    std::string color;
};


class Circle : public Shape {
public:
    Circle( int r )
        : Shape()
        , radius( r )
    {}  

    Circle() : Circle( 0 ) {}
    ~Circle() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    int getRadius() override { return radius; }; 

private:
    int radius;
};

廣場:

class Square : public Shape {
public:
    Square( int h, int w )
        : Shape()
        , height( h )
        , width( w )
    {}  

    Square() : Square( 0, 0 ) {}
    ~Square() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    int getHeight() override { return height; }
    int getWidth() override { return width; }

private:
    int height;
    int width;
};  

測試:

int main() {
    using shapes = std::vector< Shape * >;

    shapes s;
    s.push_back( new Circle( 10 ) );
    s.push_back( new Square() );
    s.push_back( new Square( 1, 3 ) );
    s.push_back( new Circle() );

    for ( Shape * sh : s ) {
        std::cout
            << " r " << sh->getRadius()
            << " h " << sh->getHeight()
            << " w " << sh->getWidth()
            << std::endl;
    }       

    for ( Shape * sh : s ) { delete sh; } s.clear();
}

輸出:

r 10 h 0 w 0
r 0 h 0 w 0
r 0 h 1 w 3
r 0 h 0 w 0
virtual Circle::~Circle()
virtual Square::~Square()
virtual Square::~Square()
virtual Circle::~Circle()

以下是使用區域示例更好地使用虛擬方法:

#include <iostream>
#include <vector>

struct Shape {
    Shape() {}
    virtual ~Shape() {}

    virtual double area() = 0;
};

擴展與不同的區域實施:

struct Circle : public Shape {
    Circle( int r )
        : Shape()
        , radius( r )
    {}

    Circle() : Circle( 0 ) {}
    ~Circle() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    virtual double area() override { return radius * radius * 3.14; }

    int radius;
};

struct Square : public Shape {
    Square( int h, int w )
        : Shape()
        , height( h )
        , width( w )
    {}

    Square() : Square( 0, 0 ) {}
    ~Square() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    virtual double area() override { return height * width; }

    int height;
    int width;
};

測試

int main() {
    using shapes = std::vector< Shape * >;

    shapes s;
    s.push_back( new Circle( 1 ) );
    s.push_back( new Square( 1, 1 ) );
    s.push_back( new Square( 2, 3 ) );
    s.push_back( new Circle( 2 ) );

    for ( Shape * sh : s ) {
        std::cout << sh->area() << std::endl;
    }

    for ( Shape * sh : s ) { delete sh; } s.clear();
}

輸出:

3.14
1
6
12.56
virtual Circle::~Circle()
virtual Square::~Square()
virtual Square::~Square()
virtual Circle::~Circle()

我希望你知道pure virtual virtual函數和virtual函數之間的區別。 Pure virtual函數本質上是沒有主體的占位符函數。 您的基類形狀更適合普通virtual函數,這些函數可以但不必在子類中更改。 取出函數聲明中的= 0部分,使函數只是普通的virtual函數。

這應該讓你朝着正確的方向前進。 通過使您的成員不是純虛擬,您可以在派生類中實現它們,但您不必這樣做。

class Shape{
    public:
    std::string getColor();

    virtual int getRadius(); //Method implemented in Circle
    virtual int getHeight(); //Method implemented in Square
    virtual int getWidth();  //Method implemented in Square

protected:
    std::string color;
};

class Circle : public Shape{
public:
    int getRadius();

private:
    int radius;
};

class Square : public Shape{
public:
    int getHeight();
    int getWidth();

private:
    int height;
    int width;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM