- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先请确保您知道 std::auto_ptr 曾经有 3 个版本。
std::auto_ptr 的第一个版本如下所示:
template<class T>
class auto_ptr
{
public:
explicit auto_ptr(T *p = 0): pointee(p) {}
// copy constructor member
// template: initialize a new auto_ptr with any compatible auto_ptr
template<class U> auto_ptr(auto_ptr<U>& rhs): pointee(rhs.release()) {}
~auto_ptr() { delete pointee; }
// assignment operator
// member template assign from any compatible auto_ptr
template<class U> auto_ptr<T>& operator=(auto_ptr<U>& rhs)
{
if (&rhs != this)
{
reset(rhs.release());
}
return *this;
}
T& operator*() const { return *get(); }
T* operator->() const { return get(); }
// return value of current dumb pointer
T* get() const { return pointee; }
// relinquish ownership of current dumb pointer and return its value
T* release() { T* p = pointee; pointee = 0; return p; }
// delete owned pointer,assume ownership of p
void reset(T *p = 0)
{
if (p != pointee)
{
delete pointee;
pointee = p;
}
}
private:
T* pointee;
};
只有接口(interface),实现起来很简单。
我的代码是这样的:
auto_ptr<int> foo()
{
auto_ptr<int> p(new int(1));
return p;
}
int main()
{
auto_ptr<int> p;
p = foo();
return 0;
}
在我看来,我的测试代码无法通过编译器。但是它通过了,当我运行它时,它因删除 ponter 两次而中断。
我跟踪汇编代码,发现流程如下,内存地址简称为低16位。
ctor: f8e4
new: 6bf0
ctor: f7d4
copy ctor: f7d4 -> f80c
dctor: f7d4 (NULL)
delete: 0
lea ecx, [ebp-0ECh] // f8e4: memory-> 6bf0
dctor: f80c (6bf0)
delete: 6bf0
dctor: f8e4 (6bf0) // twice delete
似乎代码:p = foo(); ctor 一个临时对象,它保存了 foo() 中新的内存。
关键是,为什么 p = foo() 只是改变 p.pointee,而不是调用 p.operator=() ?
我添加了第一个 auto_ptr 的实现。
与网友交谈,他指出mybe编译器生成:
auto_ptr<T>& operator=(auto_ptr<T>& rhs)
除了使用
template<class U> auto_ptr<T>& operator=(auto_ptr<U>& rhs);
我发现 std::auto_ptr 有两个 operator=。我测试手动将它添加到界面,同时编译器提示:“‘auto_ptr’无法转换为‘auto_ptr &’”。
这是关键!!!然后我需要找到原因!
当用户没有为类类型定义 operator= 时,编译器将生成一个。并与其他运算符=进行比较,选择一个更特殊的!
解决了!考虑你所有的答案!感谢您的所有评论!
最佳答案
我不确定我是否正确理解了您的问题,但您的界面实际上没有定义copy赋值运算符(也不是copy 构造函数),因为“模板复制 op=”不是真正的复制 op=(并且“模板复制构造函数”不是真正的复制构造函数)。
这里有一个简单的例子来说明这个问题:
#include <cstdio>
using std::puts;
struct M {
M& operator=(M const&) {
puts("M::operator=(M const&)");
return *this;
}
};
template<typename T> class Foo {
M m;
template<typename U> friend class Foo; // (needed for m = rhs.m; below)
public:
template<typename U> Foo& operator=(Foo<U> const& rhs) {
puts("[template] Foo<T>::operator=(Foo<U> const&)");
m = rhs.m; // calls M's op=
return *this;
}
};
int main() {
puts("===");
Foo<int> a;
Foo<double> b;
a = b;
puts("---");
Foo<int> c;
Foo<int> d;
c = d;
puts("===");
}
打印:
===
[template] Foo<T>::operator=(Foo<U> const&)
M::operator=(M const&)
---
M::operator=(M const&)
===
为什么第二个作业只有一行?那是因为 c = d;
电话 Foo<int>::operator=(Foo<int> const&)
即真正的复制赋值运算符,因为我们没有声明它(只有模板版本)编译器自动生成它(它做了成员分配,因此调用 M::operator=
)。
因此,我必须将它显式添加到类中:
// ...
Foo& operator=(Foo const& other) {
puts("[non-template] Foo<T>::operator=(Foo<T> const&)");
m = other.m;
return *this;
}
};
然后打印:
===
[template] Foo<T>::operator=(Foo<U> const&)
M::operator=(M const&)
---
[non-template] Foo<T>::operator=(Foo<T> const&)
M::operator=(M const&)
===
因此,在您的示例中,p = foo();
不会调用您的用户定义 template<class U> auto_ptr<T>& operator=(auto_ptr<U>& rhs)
但是隐式生成的版本只是分配了 pointee
成员(不发布来源)。
关于c++ - 为什么 auto_ptr 行为异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18674845/
我正在处理一些必须返回 std::auto_ptr 的旧代码,我的经验相对较少。我遇到过这样的情况: // I need to populate this function std::auto_ptr
Nicolai Josuttis 在他的书“The C++ Standard Library - A Tutorial and Reference”中,在第 44 页的以下段落中写道: Accordi
请帮助我理解以下问题。 请看下面的代码示例: #include class Shape { public: virtual wchar_t *GetName() { return L"Shape
我正在尝试创建一个将 auto_ptr 带到 Base 类的函数,我想用一个 auto_ptr 来调用它 派生类。但是我没能完成它。 我试过在没有引用的情况下使用它: void function(st
我在使用 std::auto_ptr 时遇到问题.我尝试使用 GCC 4.6.1 在 Ubuntu 11.10 上编译以下内容,我收到错误消息 error: no match for call to
我有以下代码: void do_something(Image *image) { Image *smoothed = NULL; Image *processed = NULL;
那么,如果释放 auto_ptr 拥有的对象但实际上并未将其分配给原始指针,指针会发生什么情况?似乎它应该被删除,但它永远没有机会。那么它是否会“泄露到野外”? void usingPointer(i
如果我有一个 auto_ptr,我可以将它传递给引用吗?比如: auto_ptrClass(new MyClass); void SetOponent(MyClass& oponent); //So
我正在阅读 an article关于有效使用 auto_ptr。在那里,建议将以下代码作为正确的代码段: // Example 10(c): Correct (finally!) // auto_pt
如果我有课 template struct C { ... private: auto_ptr ptr; }; 如何为 C 定义复制构造函数: 不可能 template C::C(const
auto_ptr 是否与指针大小相同? 我必须用 boost::scoped_ptr 代替它,我想知道这两种数据类型是否具有相同的大小。 最佳答案 只需执行以下操作,您就可以很容易地找出尺寸: #in
这是我的程序的示例代码。在这里,我使用 std::auto_ptr 动态分配内存并输入值(在函数中),之后我再次为同一个变量分配内存。因此,当为相同的新内存分配时,以前分配的内存将被释放。我对此表示怀
我知道这个: #include class A; class B { public: B(A* a) : a_(a) {} private: std::auto_pt
我将 auto_ptr 初始化为 NULL,稍后在游戏中我需要知道它是否为 NULL 以返回它或一个新拷贝。 我试过了 auto_ptr ret = (mReqContext.get() != 0)
我试图了解有关 auto_ptr 类如何工作的某些细节。假设您有以下类(class)(我是在一个网站上找到的,该网站上有人解释了赋值运算符的要点)。 class TFoo : public TSupe
我不太清楚 auto_ptr 在这种情况下是否会帮助我: class A { A(const B& member) : _member(B) {}; ... const B& _me
在我的代码中,我使用 new 分配一个整数数组。之后,我将这个指针包装到一个 auto_ptr 中。我知道 auto_ptr 会自动调用它的析构函数。由于我的 auto_ptr 指向一个数组(使用 n
考虑以下代码: #include struct A { std::auto_ptr i; }; A F() { A a; return a; } int main(int ar
除了使用 auto_ptr 的所有已知好处之外,auto_ptr 的“最坏做法”是什么? 创建 auto_ptr 的 STL 约束器。auto_ptr 不满足“CopyConstructable”要求
偶尔,对于转瞬即逝的时刻,我认为 auto_ptr 很酷。但大多数时候,我认识到有更简单的技术可以让它变得无关紧要。例如,如果我想自动释放一个对象,即使抛出异常,我也可以新建该对象并分配给一个 aut
我是一名优秀的程序员,十分优秀!