Lidström先生的主张是,构造shared_ptr<Base> p(new Derived);不要求Base有虚拟析构函数:
Armen Tsirunyan:"真的吗?shared_ptr会正确清理吗?在这种情况下你能否证明可以实现这种效果?"
DanielLidström:" shared_ptr使用自己的析构函数来删除Concrete实例.这在C++社区中被称为RAII.我的建议是你学习RAII的全部内容.它将使你的C++编码在使用时更加容易RAII在所有情况下."
Armen Tsirunyan:"我知道RAII,我也知道,当pn达到0时,最终shared_ptr析构函数可能会删除存储的px.但是如果px有静态类型指针
Base和动态类型指针Derived,那么除非Base有一个虚拟析构函数,会导致不确定的行为.如果我错了,请纠正我."DanielLidström:" shared_ptr知道静态类型是Concrete.它知道这个,因为我在它的构造函数中传递它!看起来有点像魔术,但我可以向你保证它是设计上的并且非常好."
所以,判断我们.如何实现shared_ptr而不需要多态类具有虚拟析构函数是否可能(如果是)?提前致谢
Java和C#支持的,不能用作与基类类的概念 final和sealed关键字.但是,在C++中,如果每个类都有一个虚拟的析构函数,那么就没有什么好的方法可以防止类的派生出于某种困境而导致类被派生出来?
编辑:从C++ 11开始,这不再是真的,你可以指定一个类final.
一方面给一个对象一个虚拟析构函数意味着它将拥有一个vtable并因此消耗4个(或64位机器上的8个)每个对象的附加字节vptr.
另一方面,如果有人后来从这个类派生并通过指向基类的指针删除派生类,程序将是错误定义的(由于没有虚拟析构函数),并且坦率地优化每个对象的指针是荒谬.
在具有虚拟析构函数的抓握手上(可以说是)宣称这种类型意味着多态地使用.
有些人认为,你需要一个明确的理由不使用虚拟析构函数(如的潜台词这个问题)和其他人说,只有当你有理由相信,你的类是从派生你应该使用它们,有什么事你认为?
编辑:这个问题出现了,我想我已经开始了!去StackOverflow !! :d
我的考试即将开始,去年考试的一个问题是通过实施以下构造函数来发现问题,并编写一个更正的问题.
Rectangle::Rectangle(string col, int len, int br)
{
setColour(col);
length =len;
breadth=br;
}
Run Code Online (Sandbox Code Playgroud)
类定义如下:
class Polygon
{
public:
Polygon(string col="red");
void printDetails(); // prints colour only
virtual double getArea()=0;
void setColour(string col);
private:
string colour;
};
class Rectangle : public Polygon
{
public:
Rectangle(string, int, int);
void printDetails(); // prints colour and area
// for part 3, delete the line below
double getArea();
private:
int length;
int breadth;
};
Run Code Online (Sandbox Code Playgroud)
我已将代码写入编译器,运行正常.我猜这个问题与继承有关,因为它string colour;是私有的,但是setColour是公开的,所以我无法弄明白.除非它Rectangle::Rectangle(string …
考虑这个例子:
#include <cstdio>
#include <memory>
struct base
{
base( int i ): i(i) { printf("base ctor\n"); }
~base() { printf("base non-virtual dtor\n"); } // non-virtual
int i;
};
struct derived : public base
{
char* s;
derived(int i): base(i), s(new char[i] )
{
printf("derived ctor\n");
}
~derived()
{
printf("derived dtor\n");
delete [] s;
}
};
int main()
{
printf("Success\n");
//raw pointer
printf("RAW-POINTER\n");
{
base* b = new derived(2);
// ......
delete b; //here memory leak, but it's old- and error-prone …Run Code Online (Sandbox Code Playgroud) class AbstractQuery {
virtual bool isCanBeExecuted()=0;
public:
AbstractQuery() {}
virtual bool Execute()=0;
};
class DropTableQuery: public AbstractQuery {
vector< std::pair< string, string> > QueryContent;
QueryValidate qv;
public:
explicit DropTableQuery(const string& qr): AbstractQuery(), qv(qr) {}
bool Execute();
};
Run Code Online (Sandbox Code Playgroud)
是否有必要在派生类构造函数中调用基础构造函数?
我对以下代码有疑问:
#include <iostream>
#include <boost/scoped_ptr.hpp>
class Interface
{
};
class A : public Interface
{
public:
A() { std::cout << "A()" << std::endl; }
virtual ~A() { std::cout << "~A()" << std::endl; }
};
Interface* get_a()
{
A* a = new A;
return a;
}
int main()
{
{
std::cout << "1" << std::endl;
boost::scoped_ptr<Interface> x(get_a());
std::cout << "2" << std::endl;
}
std::cout << "3" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
它创建以下输出:
1
A()
2
3
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它不会调用A的析构函数.我看到获取A的析构函数的唯一方法是为Interface类添加一个析构函数,如下所示:
virtual ~Interface() { }
Run Code Online (Sandbox Code Playgroud)
但我真的想避免在我的接口类中的任何实现并且virtual …
我有一个类,Tile它有一个带有Color对象参数的构造函数:
class Tile
{
public:
static const int size = 32;
Tile();
Tile(Color &color);
void render(int x, int y);
Color getColor();
~Tile();
private:
Color _color;
};
Run Code Online (Sandbox Code Playgroud)
然后我有一个子类,TileGrass继承Tile:
class TileGrass : public Tile
{
public:
TileGrass();
~TileGrass();
};
Run Code Online (Sandbox Code Playgroud)
现在的问题是TileGrass需要Tile使用Color参数继承构造函数.但是,TileGrass对象已经知道它需要给超类提供什么颜色,所以我不想Color在创建新TileGrass对象时传入对象.在Java中,我可以这样做:
public class TileGrass extends Tile {
public TileGrass() {
super(color object);
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能在C++中做这样的事情?
c++ ×7
constructor ×3
destructor ×2
c++11 ×1
class-design ×1
inheritance ×1
oop ×1
polymorphism ×1
unique-ptr ×1