C++继承:指向基类的指针能够访问派生类的成员吗?

huangapple go评论140阅读模式
英文:

c++ inheritance: can a pointer to a base class access members of the derived class?

问题

给定一个基类 Shape 和一个派生类 Rectangle,我想通过以下代码访问 Rectangle 的成员变量 size

class Shape
{
    public:
        Shape() {};
};

class Rectangle
{
    public:
        Rectangle(int width) {width=width;}
        int width;
};


// 在运行时执行这段代码
std::shared_ptr<Shape> ptr = std::make_shared<Rectangle>();
ptr->width; // 这样做可能吗?

我有一个更复杂的代码,这样会导致错误。相反,如果 compute_area()Rectangle 的重写成员函数,ptr->compute_area() 将不会报错。

英文:

Given a base class Shape and a derived class Rectangle, I want to access the member variable size of Rectangle by the following code:

class Shape
{
    public:
      Shape() {};
};

class Rectangle
{
public:
   Rectangle(int width) {width=width;}
   int width;
};


//execute this code during runtime
std::shared_ptr&lt;Shape&gt; ptr = std::make_shared&lt;Rectangle&gt;();
ptr-&gt;width; // is this possible ???

I am having a more complicated code, where this results in an error. Conversely, if compute_area() were an overwritten member function of Rectangle, ptr-&gt;compute_area() would give no error.

答案1

得分: 1

为了实现你想要的功能,你需要为Shape和Derived提供一个共同的接口来解决compute_area()

class Shape
{
public:
    virtual int metnodA() = 0;
    virtual int compute_area() = 0;
    virtual ~Shape() {};
};

class Rectangle:public Shape
{
    int width;
public:
    Rectangle(int w):width(w) {}
    int metnodA() override {
        return width;
    };
    int compute_area() override {
        //你的实现
    };
}
由于Shape没有这样的成员,直接访问width是不可能的

<details>
<summary>英文:</summary>

To make what you want you need common interface for Shape and Derived to solve `compute_area()`:

    class Shape
    {
    public:
        virtual int metnodA() = 0;
        virtual int compute_area() = 0;
        virtual ~Shape() {};
    };
    
    class Rectangle:public Shape
    {
        int width;
    public:
        Rectangle(int w):width(w) {}
        int metnodA()override {
            return width;
        };
        int compute_area() override {
            //your implementation
        };
    }
While direct access to width is impossible since `Shape` has no such member.

</details>



# 答案2
**得分**: 1

首先,您的代码存在一个大问题。Rectangle没有继承自Shape,所以```std::shared_ptr&lt;Shape&gt; ptr = std::make_shared&lt;Rectangle&gt;();```会抛出错误。您需要```class Rectangle : public Shape```来修复它。

至于通过ptr访问成员变量width,您需要将Shape转换为Rectangle。有几种方法可以做到这一点,这将取决于您的代码正在做什么。如果您百分之百确定ptr可以转换为Rectangle,您可以这样做:

std::shared_ptr<Shape> ptr = std::make_shared<Rectangle>();
auto rect = std::static_pointer_cast<Rectangle>(ptr);
rect->width; //现在您可以访问它


然而,您应该始终评估首先需要这样做的原因。像这样进行转换通常是代码中的一个很大的警告信号,表明您的设计或解决问题的方法存在缺陷。有时进行这样的转换是合适的,但是在没有看到您的其余代码的情况下,无法在这里进行评估。我建议您避免进行转换,研究为什么您需要在当前设计中这样做,并在不需要转换的情况下重新设计。这听起来比实际情况要容易一些,尤其是如果您刚开始接触编程,但是编写可维护代码是非常值得的。
<details>
<summary>英文:</summary>
First, your code contains a big problem. Rectangle does not inherit from Shape, so ```std::shared_ptr&lt;Shape&gt; ptr = std::make_shared&lt;Rectangle&gt;();``` will throw an error. You need to ```class Rectangle : public Shape``` to fix it
As for access to the member variable width via ptr, you will need to cast Shape to Rectangle. You can do it a few ways, which will depend on what you&#39;re code is doing. If you are 100% sure ptr can cast to Rectangle, you can do this:

std::shared_ptr<Shape> ptr = std::make_shared<Rectangle>();
auto rect = std::static_pointer_cast<Rectangle>(ptr);
rect->width; // you can now access it


However, you should always evaluate your need to do this in the first place. Casting like this is usually a really big code smell that indicates a flaw in your design or approach to the problem. There are times when it is appropriate to make cast like this, but without seeing the rest of your code there is no way to make that assessment here. I suggest you avoid casting, look into why you need to do it with your current design, and redesign around not needing the cast. This sounds easier than it is, especially if you are new to it, but it is well worth doing for writing maintainable code.
</details>

huangapple
  • 本文由 发表于 2023年3月9日 18:59:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683678.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定