- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道标题很烂。这里的问题是我有一个从形状类继承的 2D 和 3D 形状类
class Shape {
public:
virtual double area() = 0;//Calculates the area of some kind of shape
~Shape() { delete this; }
};
class Shape2D :public Shape {
public:
virtual double perimeter() = 0;//Calculates the perimeter of some kind of 2D-shape
~Shape2D() {};
};
class Shape3D :public Shape {
public:
virtual double volume() = 0;//Calculates the volume of some kind of 3D-shape, area function will return surface area
~Shape3D() {};
};
决定所有形状都默认有一个区域。在 2D 形状中,它将有一个虚拟周长方法以及来自 Shape 的面积。在 3D 形状中,它将有一个体积,并且虚拟面积方法将被视为表面积。
我采用的方法是在可以选择 2d 或 3d 形状的菜单中:在 2d 菜单中,我启动:
Shape2D * s = nullptr;
在 3d 菜单中,我将启动:
Shape3D * s = nullptr;
然后为了显示任何信息,我使用以下方法:
void displayShape2D(Shape2D *)
和
void displayShape3D(Shape3D *)
但是,我想采用的方式是声明:
Shape *s = nullputr;
在 main 的开头,然后在用户选择的任何形状,我可以设置:
s= new Triangle()
或
s = new cube();
初始化工作正常,但是当我尝试创建一个显示方法时,这就是我遇到问题的地方。我希望能够做到:
displayShape(Shape *s)
当给定一个 2d 形状并在我尝试的方法中时:
cout <<s->perimeter();
它会说周边成员不在形状类中。然后的问题是试图能够确定形状是 2d 还是 3d,然后显示 2d 的面积和周长或 3d 的表面积和体积。这是可能的还是在专用菜单中创建形状类型然后使用专用显示方法是唯一的出路?
最佳答案
虽然其他答案“有效”,但这不是我在这里采用的方法。基本上,您希望根据实例的动态类型执行不同的代码:这就是虚函数的用途。
所以只需添加一个(可能是纯的)虚拟 display
Shape
的成员函数类并在派生类中相应地实现它。
与dynamic_cast
相反当您添加更多派生类或“进一步”派生的类时,这种方法不会中断。
最后:
~Shape() {
delete this;
}
这个析构函数在 C++ 中相当于拿着猎枪朝自己的脸开枪。对于堆栈或静态分配的实例,这将导致虚假释放(因为该实例从未从堆中分配),对于堆分配,它将导致双重释放(因为析构函数在释放占用的内存之前被调用)实例)。
在您的情况下,您必须做的是使析构函数成为虚拟的。否则,只有 Shape *
不可能正确地销毁指向的实例!
这就是这种“显示”功能“普遍”实现的方式,至少据我所知:
struct Shape {
virtual void write_to(ostream &) const = 0;
virtual ~Shape() {}
};
struct Shape2D : public Shape {
void write_to(ostream & stream) const {
stream << "<2D, whooo>";
}
};
struct Shape3D : public Shape {
void write_to(ostream & stream) const {
stream << "<I got depth, man!>";
}
};
ostream & operator<<(ostream & stream, Shape const & shape) {
shape.write_to(stream);
return stream;
}
现在可以写任何Shape
(当使用指针时,取消引用它)任何 ostream,C++“风格”:
std::unique_ptr<Shape> awesomeShape = std::make_unique<Shape2D>();
std::cout << "Awesome is: " << *awesomeShape << std::endl;
在这里,首先operator<<(ostream &, Shape &)
被调用(对于任何 Shape
类似的东西)调用虚拟成员函数 write_to
,它以不同的方式为每个派生类实现(尽管在 Shape
中也可能有一个通用的实现!)。另见 this .
dynamic_cast
可能存在的问题当您加深层次结构时,就会出现这种方法:
struct ThickShape2D : public Shape2D {
// whatever
};
具有动态类型的实例 ThickShape2D
也可以是dynamic_cast
到 Shape2D
,因此您需要密切注意这些 if 子句的顺序。
但是,引用 Jarra McIntyre 的话:
I think it is worth mentioning that the design trade offs between using virtual functions and the above approach (and any other approaches) are complex. The above approach allows runtime dispatch on multiple types, and simplifies things such as (going back to the above) having multiple draw functions.
我完全同意。有访问者模式(也是非循环变体),可能是命令模式,如果需要更多信息,可以开始查看许多其他内容。有关(原始)RTTI 使用的广泛讨论,请参阅 this question and its answers .
作为最后的说明:我不确切知道您要建模的是什么,但考虑到继承通常不是可用的最佳方法。如果可能,prefer composition over inheritance . Entity component系统是一个很好看的东西。
(上面的段落包含6个链接,只是为了不要错过任何东西。)
关于c++ - 使用形状参数时,如何灵活地使用可以处理 2D 和 3D 形状的方法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35821864/
我有以下几行代码: using XXX.PAD.PaidServices; using YYY= XXX.PAD.PaidServices.Judet; //// uncomment below fo
我正在寻找一种方法,让 LAN 中的客户端无需任何配置即可找到我的服务器应用程序的所有实例。我不想自己破解某些东西,而是想使用现有的解决方案。就个人而言,我需要用 Python 完成它,但我很乐意听到
我的“问题”或“挑战”有很多问题。但它们都不符合我的需求。好的,我开始了: 我想要一个保存可变属性的数据库。现在我将它们作为列名“硬编码”到数据库中(参见图片)。请参阅“颜色”和“尺寸”。但是如果我想
我正在为我的一个 friend 创建一个网站。我们得到了这些布局,我已经放了一个灵活的背景,可以缩放到当前的浏览器大小。但是放置在背景上的图标需要在缩放窗口时保持相对位置。意味着如果我调整窗口大小,让
案例 通常,您会使用 cellForRowAtIndexPath 委托(delegate)方法来设置单元格。单元格的信息集对于单元格的绘制方式和大小非常重要。 不幸的是,heightForRowAtI
我试图让下面的 div 变得灵活 div { min-width: 500px; max-width: 1000px; width:100%; height: 400px; margin-left:1
我在单元测试方面遇到问题。当我运行测试时,它以 "No tests found" 结束。我正在使用 AppCode 和 Quick/Nimble 框架进行单元测试,但它在 XCode 中也不起作用。
问之前,请理解我的英语不好。 我在 servlet 编程中使用 Class.forName(...) 类。当我访问 servlet 时,我从数据库中获得一行详细的 Controller 信息,指示要使
我创建了一个cron job在 GAE 灵活环境中,每 15 分钟自动运行一次。 但是在创建每个实例时,是否会为每个实例复制相同的 cron 作业?我对此不太确定。 最佳答案 不,不会为每个实例复制
div A 灵活且固定(位于窗口顶部),具有高 z-index,因此下方的元素可以在滚动时从下方通过。 div B 位于 div A 下方,我希望它“粘”在 div A 的底部,因为在调整窗口大小时高
我是 Quick/Nimble 的新手,所以我尝试了一个简单的单元测试: import Quick import Nimble class DarkSkyTests: QuickSpec {
我创建了一个演示。关于表格单元格的灵 active ,我需要一些帮助。 我有一些表格单元格,它们的宽度应该是固定的。 但单元格由标签组成,标签可以是长文本,也可以是短文本。 基于此标签,表格单元格应该
我非常熟悉在代码中需要“水平带”的网站 - 即使他们的内容固定在 960 像素以内,他们的背景也会向左和向右“延伸”。 我知道如何做这些,如果它们只有一种颜色,或者我可以用作背景的一张图片。 最近一位
我在自己编写的网站(无框架或 CMS)上使用 Cloudflare Flexible SSL。一切正常,现在我想在整个网站上使用 HTTPS。我在 Apache Web 服务器上使用 PHP。 我想知
我有这个 Java 接口(interface): public interface Box { public void open(); public void close(); } 这个接
所以我有一个“主要”功能系统,现在可以作为 CMS 使用:用户进入编辑器并从四个模板中选择一个。在模板中,他们单击可以添加图像、文本或两者的部分。 我有一个预览屏幕,可以向他们展示他们正在制作的东西,
下面的 HTML/CSS/Javascript (jQuery) 代码显示了 #makes 选择框。选择一个选项会显示带有相关选项的 #models 选择框。 #makes 选择框偏离中心,#mode
我正在使用固定高度的图像来填充具有渐变颜色的 div,方法如下:背景:透明 url(green_bg.gif) repeat-x scroll 0 0; 但是它只填充一个等于图像高度的高度。根据其中的
我的系统的 GUI 在 1366 X 768 分辨率下运行良好。当它以不同的分辨率显示时,我需要并排滚动,而它不应该这样。此外,当我尝试在 chrome 中按 ctr+- 时,div 和部分变得困惑。
我正在尝试在 google app engine 灵活环境中使用 python 编写日志。 我想使用默认的 python 日志记录库并使用处理程序进行日志记录。这是我的代码: import loggi
我是一名优秀的程序员,十分优秀!