关于C++设计模式的问题,纯虚方法调用
Posted
技术标签:
【中文标题】关于C++设计模式的问题,纯虚方法调用【英文标题】:Question on C++ design pattern, pure virtual method called 【发布时间】:2021-04-09 02:50:44 【问题描述】:我在尝试来自https://en.wikipedia.org/wiki/Bridge_pattern 的代码时遇到了虚拟方法问题。
错误信息是:
调用纯虚方法 在没有活动异常的情况下调用终止 中止(核心转储)
代码是用g++ -o bridge bridge.cpp -std=c++11
编译的
为什么drawing_api_.DrawCircle()
调用DrawingAPI
中的虚函数?
#include <iostream>
#include <string>
#include <vector>
class DrawingAPI
public:
virtual ~DrawingAPI() = default;
virtual std::string DrawCircle(float x, float y, float radius) const = 0;
;
class DrawingAPI01 : public DrawingAPI
public:
std::string DrawCircle(float x, float y, float radius) const override
return "API01.circle at " + std::to_string(x) + ":" + std::to_string(y) +
" - radius: " + std::to_string(radius);
;
class DrawingAPI02 : public DrawingAPI
public:
std::string DrawCircle(float x, float y, float radius) const override
return "API02.circle at " + std::to_string(x) + ":" + std::to_string(y) +
" - radius: " + std::to_string(radius);
;
class Shape
public:
Shape(const DrawingAPI& drawing_api) : drawing_api_(drawing_api)
virtual ~Shape() = default;
virtual std::string Draw() const = 0;
virtual float ResizeByPercentage(const float percent) = 0;
protected:
const DrawingAPI& drawing_api_;
;
class CircleShape: public Shape
public:
CircleShape(float x, float y, float radius, const DrawingAPI& drawing_api)
: Shape(drawing_api), x_(x), y_(y), radius_(radius)
std::string Draw() const override
return drawing_api_.DrawCircle(x_, y_, radius_);
float ResizeByPercentage(const float percent) override
return radius_ *= (1.0f + percent/100.0f);
private:
float x_, y_, radius_;
;
int main(int argc, char** argv)
std::vector<CircleShape> shapes
CircleShape1.0f, 2.0f, 3.0f, DrawingAPI01,
CircleShape5.0f, 7.0f, 11.0f, DrawingAPI02
;
for (auto& shape: shapes)
shape.ResizeByPercentage(2.5);
std::cout << shape.Draw() << std::endl;
return 0;
【问题讨论】:
避免引用持有DrawingAPI
。一些 Wikipedia 实现的 C++ 设计模式示例存在错误。
非常感谢,修改指针的引用后问题解决了。
【参考方案1】:
发布的代码有问题——尤其是Shape
类包含对a-DrawingAPI-object 的引用:
class Shape
[...]
protected:
const DrawingAPI& drawing_api_;
;
...但是它所引用的对象是一个临时对象,一旦main()
中的CircleShape
构造函数返回,就会被销毁。
避免错误的一种方法是声明 DrawingAPI01
和 DrawingAPI02
对象,使其生命周期比引用它们的 CircleShape
对象的生命周期更长,例如通过将main()
更改为如下所示:
int main(int argc, char** argv)
DrawingAPI01 api01; // declaring these up here keeps them valid
DrawingAPI01 api02; // until the end of main()
std::vector<CircleShape> shapes
CircleShape1.0f, 2.0f, 3.0f, api01,
CircleShape5.0f, 7.0f, 11.0f, api02
;
for (auto& shape: shapes)
shape.ResizeByPercentage(2.5);
std::cout << shape.Draw() << std::endl;
return 0;
【讨论】:
以上是关于关于C++设计模式的问题,纯虚方法调用的主要内容,如果未能解决你的问题,请参考以下文章