isa*_*nae 7 c++ inheritance destructor
vector我有一个带有成员变量的类T,该变量已声明但未定义。如果没有定义该类的析构函数,这可能会出现问题,因为编译器可能会选择其他一些翻译单元来生成析构函数。如果该 TU 没有 的定义,则T编译会失败。
struct undefined;
struct S
{
S(int);
std::vector<undefined> v;
};
int main()
{
S s(42); // fails in ~vector(), `undefined` is undefined
}
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我通常在实现该类的文件中添加一个默认的析构函数作为锚点,该类可以访问该定义。
struct undefined;
struct S
{
S(int);
~S(); // implemented in another TU as `S::~S() = default;`
std::vector<undefined> v;
};
int main()
{
S s(42); // ok
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试对继承基类构造函数的派生类执行相同的操作:
#include <vector>
struct undefined;
struct base
{
base(int);
};
struct derived : base
{
using base::base;
~derived();
std::vector<undefined> v;
};
int main()
{
derived d(1); // fails in ~vector(), `undefined` is undefined
}
Run Code Online (Sandbox Code Playgroud)
如果我更改derived为不继承构造函数,则编译成功:
#include <vector>
struct undefined;
struct base
{
base(int);
};
struct derived : base
{
//using base::base; <--- note
derived(int);
~derived();
std::vector<undefined> v;
};
int main()
{
derived d(1); // ok
}
Run Code Online (Sandbox Code Playgroud)
真正让我困惑的是 clang 是这么说的:
stl_vector.h:336:35: error: arithmetic on a pointer to an incomplete type 'undefined'
[blah]
a.cpp:12:14: note: in instantiation of member function 'std::vector<undefined>::~vector' requested here
using base::base;
^
Run Code Online (Sandbox Code Playgroud)
听起来好像using base::base也带来了一些破坏的东西vector,但我不知道是什么。我尝试删除两个类中的复制/移动构造函数/运算符,但错误仍然存在。g++ 和 Visual C++ 都会失败并出现类似的错误。
这是怎么回事?
正如Raymond Chen在此评论中提到的,之所以using base::base需要vector析构函数,是因为构造函数可能会抛出异常,这可能需要销毁成员变量。唯一的解决方案是手动编写构造函数。
如果抛出异常,构造函数需要销毁完全构造的成员变量。在此示例中,a必须被销毁,但不能b:
std::string throws()
{
throw 1;
}
struct S
{
std::string a, b;
S() : a(""), b(throws()) {}
};
Run Code Online (Sandbox Code Playgroud)
在下一个示例中,编译器生成默认构造函数和析构函数。两者都可以调用~vector(),因此都需要定义incomplete:
struct incomplete;
struct S
{
std::vector<incomplete> v;
};
int main()
{
S s; // error
}
Run Code Online (Sandbox Code Playgroud)
为两者添加声明可以修复错误:
struct incomplete;
struct S
{
std::vector<incomplete> v;
S();
~S();
};
int main()
{
S s; // ok
}
Run Code Online (Sandbox Code Playgroud)
但是继承的构造函数也是由编译器生成的,因此需要~vector()在抛出异常的情况下使用:
struct undefined;
struct base
{
base(int);
};
struct derived : base
{
std::vector<undefined> v;
using base::base; // <- needs ~vector() in case of exceptions
~derived();
};
Run Code Online (Sandbox Code Playgroud)
因此唯一的解决方案是手动声明构造函数并在其他地方实现它。
| 归档时间: |
|
| 查看次数: |
222 次 |
| 最近记录: |