C ++唯一指针

时间:2014-05-20 19:14:19

标签: c++

class Person
{
public:
    string s;
    ~Person(){ cout << "Destructor" << endl; }
};
void _Person(Person a){ cout << a.s << endl; }
auto main() ->int
{
    unique_ptr<Person> p{new Person()};
    _Person(*p); 
    cout << "New Line" << endl;
   return 0;
}

输出:

Destructor
New Line
Destructor

为什么要打印&#34; Destructor&#34;两次?

2 个答案:

答案 0 :(得分:3)

因为您在代码中创建了两个Person对象。

在您的代码中查看此解释:

class Person // declare a class Person
{
public:
    string s;
    ~Person(){ cout << "Destructor" << endl; }
};

// function that takes a class Person as argument
void _Person(Person a) {
  cout << a.s << endl;
}


auto main() ->int
{
    unique_ptr<Person> p{new Person()}; // creation of one instance
    _Person(*p);                        // creation of second instance,
    // because p is passed by value, which means that the default copy constructor of the
    // class Person is activated, thus another object is created!!

    // when the function you called terminates, the copy goes out of scope,
    //thus ~Person() is called
    cout << "New Line" << endl;
    return 0;
}
// the object you created by new, now goes out of scope and gets deleted,
//thus ~Person() is called

但是unique_ptr允许我们创建另一个对象吗?

当然。查看ref

这些指针 unique 用于删除对象。

[编辑]

考虑到这一点:

单身确保只有一个类型。

unique_ptr确保只有一个智能指针到任何实例。

Source

[EDIT.2]

来自chris的

Nice link,其中讨论了使用下划线的规则。

为了简洁,我建议改变这个:

_Person()

到这个

Person()

这不是编译错误,只是不常见。

[EDIT.3]

通常在C ++中,您可以将类对象作为引用传递,以避免复制。当对象是 big 类的实例时,复制可能需要一些时间。

所以,我建议你改变你的功能:

void Person(Person a) {
  cout << a.s << endl;
}

到这个

void Person(Person& a) {
  cout << a.s << endl;
}

再次运行您的代码。你能猜出现在的输出是什么吗?我们通过引用传递实例,因此不会调用Person的复制构造函数。

答案 1 :(得分:2)

这是因为你的功能

void _Person(Person a){ cout << a.s << endl; }

按值获取参数,以便创建对象的副本。

auto main() ->int
{
    unique_ptr<Person> p{new Person()};
    _Person(*p);                // this calls a function _Person 
                                // with a copy of what p points to
                                // this copy dies at the end of function scope
    cout << "New Line" << endl; // its dctor has been just called
   return 0;
}                               // and now is called dctor for original variable