问题描述
在我说,包含auto_ptr的类可以存储在向量中,前提是该类具有用户定义的复制构造函数。
In an answer to http://stackoverflow.com/questions/700588/is-it-safe-to-store-objects-of-a-class-which-has-an-stdautoptr-as-its-member-v I stated that a class that contained an auto_ptr could be stored in a vector provided the class had a user-defined copy constructor.
有几个意见表明这不是这样,所以这个问题是一个尝试来解决问题。考虑下面的代码:
There were several comment suggesting that this was not the case, so this question is an attempt to clear the issue up. Consider the following code:
#include <memory>
#include <vector>
using namespace std;
struct Z {};
struct A {
A( Z z )
: p( new Z(z) ) {}
A( const A & a )
: p( a.p.get() ? new Z( *a.p.get()) : 0 ) {}
// no assigment op or dtor defined by intent
auto_ptr <Z> p;
};
int main() {
vector <A> av;
Z z;
A a(z);
av.push_back( a );
av.push_back( A(z) );
av.clear();
}
请检查上述&在你的回复中指出,对于以这种特定方式使用的特定类,可能发生未定义的
行为在C ++标准的含义中。我不感兴趣的类是有用的,良好的行为,可排序,或它如何在例外下执行。
Please examine the above & in your reply indicate where undefined behaviour in the meaning of the C++ Standard could occur for this particular class used in this particular way. I am not interested whether the class is useful, well-behaved, sortable, or how it performs under exceptions.
请注意,这不是一个问题关于创建auto_ptrs的向量的有效性 - 我非常清楚这个问题。
推荐答案
尝试将地点列表放在一起,使示例未定义行为。
Trying to put the list of places together that makes the example undefined behavior.
#include <memory>
#include <vector>
using namespace std;
struct Z {};
struct A {
A( Z z )
: p( new Z(z) ) {}
A( const A & a )
: p( a.p.get() ? new Z( *a.p.get()) : 0 ) {}
// no assigment op or dtor defined by intent
auto_ptr <Z> p;
};
int main() {
vector <A> av;
...
}
我将检查一行其中使用您的类型 A
实例化向量。标准必须说
I will examine the lines up to the one where you instantiate the vector with your type A
. The Standard has to say
在 23.1 / 3
:
在 23.1 / 4
(强调我):
+-----------+---------------+---------------------+
|expression |return type |postcondition |
+-----------+---------------+---------------------+
|t = u |T& |t is equivalent to u |
+-----------+---------------+---------------------+
表64
在 12.8 / 10
:
X& X::operator=(const X&)
if
- X的每个直接基类B具有参数为const B&
的复制赋值运算符。或B和对于类型类型M(或其数组)的X的所有非静态数据成员 - ,每个这样的类类型具有参数为类型const M& const,volatile M&或M。
否则,隐式声明的复制赋值运算符的形式为
Otherwise, the implicitly declared copy assignment operator will have the form
X& X::operator=(X&)
和第二个最后一句)
在 17.4.3.6/1和/ 2
:
特别地,在以下情况下未定义效果:
In particular, the effects are undefined in the following cases:
- 用于在实例化模板组件时用作模板参数的类型,如果类型上的操作不实现适用的要求子句的语义(20.1.5, 23.1,24.1,26.1)。这种类型的操作可以通过抛出异常来报告失败,除非另有规定。
你将看到 auto_ptr
的规范,你会注意到它有一个复制赋值运算符,它接受一个非const auto_ptr
。因此,类的隐式声明的复制赋值操作符将也采用非const类型作为其参数。如果你仔细阅读上面的地方,你会看到它如何说,实例化一个矢量与你的类型写为是未定义的行为。
Now, if you look at the specification of auto_ptr
you will note it has a copy-assignment operator that takes a non-const auto_ptr
. Thus, the implicitly declared copy assignment operator of your class will also take a non-const type as its parameter. If you read the above places carefully, you will see how it says that instantiating a vector with your type as written is undefined behavior.
这篇关于包含auto_ptr的类存储在向量中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!