#include <stdlib.h>
#include <iostream>
#include <memory>
#include "copy_of_auto_ptr.h"
#ifdef _MSC_VER
#pragma message("#include <string>")
#include <string>
// http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas
#endif
/*
case 1-4 is the requirement of the auto_ptr.
which form http://ptgmedia.pearsoncmg.com/images/020163371X/autoptrupdate/auto_ptr_update.html
*/
/*
case 1.
(1) Direct-initialization, same type, e.g.
*/
std::auto_ptr<int> source_int() {
// return std::auto_ptr<int>(new int(3));
std::auto_ptr<int> tmp(new int(3));
return tmp;
}
/*
case 2.
(2) Copy-initialization, same type, e.g.
*/
void sink_int(std::auto_ptr<int> p) {
std::cout << "sink_int << " << *p << std::endl;
}
/*
case 3.
(3) Direct-initialization, base-from-derived, e.g.
*/
class Base {
public:
Base() {
std::cout << "creating Base object..." << std::endl;
}
virtual ~Base(){
std::cout << "destoring Base object..." << std::endl;
}
virtual void go(){
std::cout << "Base::go()" << std::endl;
}
};
class Derived : public Base {
public:
Derived() {
std::cout << "creating Derived object..." << std::endl;
}
~Derived(){
std::cout << "destoring Derived object..." << std::endl;
}
void go(){
std::cout << "Derived::go()" << std::endl;
}
};
std::auto_ptr<Derived> source_derived() {
// return std::auto_ptr<Derived>(new Derived());
std::auto_ptr<Derived> tmp(new Derived());
return tmp;
}
/*
case 4.
(4) Copy-initialization, base-from-derived, e.g.
*/
void sink_base( std::auto_ptr<Base> p) {
p->go();
}
int main(void)
{
/*
// auto_ptr
*/
// case 1. // auto_ptr
std::auto_ptr<int> p_int(source_int());
std::cout << *p_int << std::endl;
// case 2. // auto_ptr
sink_int(source_int());
// case 3. // auto_ptr
std::auto_ptr<Base> p_derived(source_derived());
p_derived->go();
// case 4. // auto_ptr
sink_base(source_derived());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在Eclipse(GNU C++.exe -v gcc version 3.4.5(mingw-vista special r3))中有两个编译错误:
描述资源路径位置类型初始化参数1
void sink_base(std::auto_ptr<Base>)' from result ofstd :: auto_ptr <_Tp> :: operator std :: auto_ptr <_Tp1>()[with _Tp1 = Base,_Tp = Derived]'auto_ptr_ref_research.cpp auto_ptr_ref_research/auto_ptr_ref_research 190 C/C++问题说明资源路径位置类型没有匹配函数用于调用`std :: auto_ptr :: auto_ptr(std :: auto_ptr)'auto_ptr_ref_research.cpp auto_ptr_ref_research/auto_ptr_ref_research 190 C/C++问题
但它在VS2010 RTM中是正确的.
问题:
哪个编译器代表ISO C++标准?
案例4的内容是"auto_ptr&auto_ptr_ref想解决?"的问题.
我认为缩短版本是:
struct X
{
X() {}
X(X&);
};
X make() { return X(); }
void receive(X ) { }
int main()
{
receive(make());
}
Run Code Online (Sandbox Code Playgroud)
注意复制构造函数的异常形式(来自非const引用),它阻止(通过标准,GCC是正确的)从临时(结果make())复制构造实例的能力.
这种情况更加复杂,因为std::auto_ptr尝试使用包装器来解决由此产生的限制auto_ptr_ref.但是,由于您还希望更改指针的类型,它可能会在所有这些隐式转换的情况下分解,并且VC++只能通过非标准扩展(允许将rvalues绑定到非常量引用)来编译它.
编译器实际上告诉我正确的.在问题上:
warning C4239: nonstandard extension used : 'argument' :
conversion from 'std::auto_ptr<_Ty>' to 'std::auto_ptr<_Ty> &'
Run Code Online (Sandbox Code Playgroud)
无论如何,这std::auto_ptr是一个奇怪的语义失败的实验,并在下一个标准中被弃用.在C++ 0x中(例如使用gcc 4.4.1),如果替换了所有出现的auto_ptrwith unique_ptr,并更改了sink函数的签名,则使用rvalue引用来获取所有权转移.
void sink_base( std::unique_ptr<Base>&& p);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
649 次 |
| 最近记录: |