繁体   English   中英

初始化基类的引用成员

[英]Initialize reference member of base class

经过长时间的禁欲,我目前正在尝试刷新我的C ++技能。 因此,我正在实施一个很小的图像绘制圆图程序。

场景:我有一个名为Shape的基类,该基类实质上由一个成员组成,该成员是对表示中心的Point的引用。 是一种形状 ,除了中心外,还具有半径。

class Shape
{

public:
    Shape(Point& p);
    ~Shape();
    Point& get_center() const;

private:
    Point& center;
};

-

class Point
{
public:
    Point();
    Point(float x, float y);
    Point(short d);
    ~Point();
    float get_x() const;
    float get_y() const;
    friend std::ostream& operator<< (std::ostream& stream, const Point& p);

private:
    short dimension;
    float x, y;
};

//.cpp
std::ostream& operator<<(std::ostream &strm, const Point &p) {
    return strm << "Point(" << p.get_x() << "," << p.get_y() << ")";
}

-

class Circle :
    public Shape
{
public:
    Circle(Point p);
    Circle(Point p, float radius);
    ~Circle();
    float get_radius() const;

private:
    float radius;
    typedef Shape super;
};

成员的初始化如下:

Circle::Circle(Point p, float rad) : Shape(p), radius(rad)
{
    std::cout << "Called circle constructor with center point " << p << std::endl;
}

Shape::Shape(Point& p) : center(p) {
    std::cout << "Called Shape constructor with point " << p << "a" <<std::endl;
}

如果我随后运行以下代码,则似乎没有正确设置center变量,导致下面给出了OutputA。 奇怪的是,如果我向Shape构造函数添加更多输出(在此示例中为字母“ a”),则似乎已设置了对中心Point的引用(输出B)。 此外,两个Circle似乎都引用相同的Point ?!。 有人可以解释为什么会这样吗,以及处理这种情况的合适方法是什么?

Circle& cir1 = *(new Circle(Point(400, 550), 50));
Circle& cir2 = *(new Circle(Point(300, 550), 80));

vector<Circle> circles { cir1, cir2 };

cout << "Iterating circles" << endl;
for (auto& cir : circles)
{
    cout << "Radius: "<< cir.get_radius() << " center: " << cir.get_center() << endl;
}

输出A:

Called Shape constructor with point Point(400,550)
Called circle constructor with center point Point(400,550)
Called Shape constructor with point Point(300,550)
Called circle constructor with center point Point(300,550)
Iterating circles
Radius: 50 center: Point(1.87436e-38,1.87419e-38)
Radius: 80 center: Point(1.87436e-38,1.87419e-38)

输出B:

Called Shape constructor with point Point(400,550)a
Called circle constructor with center point Point(400,550)
Called Shape constructor with point Point(300,550)a
Called circle constructor with center point Point(300,550)
Iterating circles
Radius: 50 center: Point(300,550)
Radius: 80 center: Point(300,550)

这里有一个问题:

Circle::Circle(Point p, float rad) : Shape(p), radius(rad)

{
    std::cout << "Called circle constructor with center point " << p << std::endl;
}

Shape::Shape(Point& p) : center(p) {
    std::cout << "Called Shape constructor with point " << p << "a" <<std::endl;
}

因为Shape存储了对Circlep参数的引用。 施工结束时,该参数消失。

我可能不会存储参考,但会存储一个值。 这样,您就可以复制参数。 复制一个Point不是很昂贵。

Shape类的正确接口可能如下所示:

class Shape
{
public:
    explicit Shape(const Point& p); //const Point& ensures you can all that constructor with an R-value
    virtual ~Shape();

    const Point& get_center() const;
private:
    Point center;

};

同样,您的Circle类也应在构造函数中使用const Point&。

关于你的主程序,也许做这样的事情

std::shared_ptr<Circle> cir1(new Circle(Point(400, 550), 50));
std::shared_ptr<Circle> cir2( new Circle(Point(300, 550), 80));

vector< std::shared_ptr<Circle> > circles { cir1, cir2 };

cout << "Iterating circles" << endl;
for (auto cir : circles)
{
    cout << "Radius: "<< cir->get_radius() << " center: " << cir->get_center() << endl;
}

有关您的代码的问题是,您正在引用R值(例如,请参见http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and- c )。 希望能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM