c++ - 如何将 Parent* 对象(指向 &Child 对象)插入 vector<Child> 中?

标签 c++ inheritance

<分区>

我提供了重现错误的极其简化的代码版本。

class Shape {
    public:
        virtual void func()=0;
};

class Circle : public Shape {
    public:
        Circle() {  }
        void func() { }
};

class Square : public Shape {
    public:
        Square() {  }
        void func() { }
};

int main() {
    Circle c;
    std::vector<Circle> circs;

    std::vector<Shape*> shapes;

    shapes.push_back(&c);

    circs.push_back(shapes[0]); //ie, the Circle object that was just pushed into the 'shapes' vector.

}

我知道,就目前而言,这在功能上是无用的,我可以将 Circle 对象插入 vector - 然而,为了与形状类比保持一致,我的项目也有三角形、正方形等。我处理数据使用接受 Shape& 作为参数的函数,这样我就可以将所有形状发送到一个函数,而不是为每个形状单独的函数。这不是重点,但可以深入了解我为什么要在简化代码中做我正在做的事情。

此代码中的最后一行将不起作用。 谁能告诉我为什么?或者为我提供解决方案/解决方法?这被认为是糟糕的编程风格吗?

编辑:所以我已经解决了我遇到的对象切片问题。对于有相同问题的任何人,请在以下线程中查看 fgp 的回答:

What is object slicing?

我使用以下方法来帮助实现我正在尝试做的事情(将 Circle 对象移动到 Shape*,计算一些东西,然后将 Circle(这位于 Shape* vector 中),到它的最终位置,一个 Circle vector :

class Shape {
public:
    virtual Shape& operator=(const Shape& s) {
        assign(s);
        return *this;
    }

    virtual std::string getName() = 0;
    virtual         int getEdges() = 0;



protected:
    std::string name;
    int         edges;

    void assign(const Shape& s) {
        this->name = s.name;
        this->edges = s.edges;
    }
};

class Circle : public Shape {
private:
    int radius;
public:
    Circle() { name = "Circle"; edges = 1; }
    Circle(int rad) { name = "Circle"; edges = 1; radius = rad; }

    virtual Circle& operator=(const Shape& s) {
        if (const Circle* c = dynamic_cast<const Circle*>(&s))
            assign(*c);
        else{
            std::cout << "BAD ASSIGNMENT IN CIRCLE.";
                    //THROW ERROR HERE INSTEAD OF THE ABOVE COUT
            }
        return *this;
    }

    std::string getName() { return name; }
            int getEdges() { return edges; }
            int getRadius() { return radius; }
           void setRadius(int r) { radius = r; }

protected:
    void assign(const Circle& c) {
        Shape::assign(c);
        this->radius = c.radius;
    }

};

int main() {
    std::vector<Shape*> shapes;
    std::vector<Circle> circs;
    Circle c2(5); //Creates a circle with 5 for the radius.

    shapes.push_back(&c2); //Pushing the 5-radius circle into the Shapes* vector
    Circle c3; //Creates a circle with default constructor (which does NOT define radius)
    c3 = *shapes[0]; //Now, the overloaded assignment operator. Look at Circle::assign(const Shape&) function
    circs.push_back(c3); //We push our newly assigned circle to our Circle vector
    std::cout << "c3 radius: " << circs[0].getRadius(); //This will be 5!
}

看到这部作品真是惊喜! c3 现在知道 c2 的半径,表明重载赋值运算符适用于 Shape->Circle 转换。

如果有人有什么建议,请告诉我! (我将创建一个采用 (const Shape&) 参数的 Circle 构造函数,因此我可以使用 Circle c = *shapes[0],而不必将行,因为它找不到接受该参数的构造函数)。

EDIT2:此外,如果您使用它,请确保您抛出错误(我在您应该留下评论的地方留下了评论)。

最佳答案

一般来说,按照你的意愿做这样的事情是一个坏主意。但是要直接回答问题:

Circle* t = dynamic_cast<Circle*>(shapes[0]);
if(t) //make sure dynamic cast succeeded
  circs.push_back(*t);

您必须将引用转换为 Circle 类型,因为它是一个 Shape。

正如我之前提到的,这并不理想。你真正应该做的是让你的代码按照多态原则工作。使用抽象基类对你有利!否则,这可能会导致未定义的行为,尤其是当形状可能在更实际的代码中存储的不仅仅是圆时。

关于c++ - 如何将 Parent* 对象(指向 &Child 对象)插入 vector<Child> 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24219409/

相关文章:

c++ - 在我们的 c++ 程序中包含巨大的字符串?

c++ - Win32 API - 将 LO/HIWORD 转换为 HANDLE

c++ - 案例 'p' 的问题 || 'P' : syntax within a switch statement in C++

php - 如何调用祖 parent 方法而不出现 E_STRICT 错误?

c++ - 将构造函数值从子类传递到父类(super class) C++

ios - 覆盖 UIScrollView 子类中的委托(delegate)属性

c++ - Poco C++ 构建嵌套的 JSON 对象

java - 如何在不同实现/类/等的java中调用toString()

java - 如何使用 Spring MVC 的单表继承获取子类属性

c++ - 指向存储在 map 容器中的数据的指针