工作原理 - 指针/ Unique_ptr没有新的

时间:2014-03-06 07:00:44

标签: c++ pointers undefined-behavior unique-ptr

foo.h中

#include <iostream>
#include <memory>

class Bar
{
public:
    Bar() {};
    ~Bar() {};
    void print() {
        std::cout << "hello";
    }
};

class Foo
{
public:
    Foo(); 
    ~Foo();
    void use() {
        pteste->print();
    }
private:
    std::unique_ptr<Bar> pteste;
};

#endif

的main.cpp

#include <memory>
#include "foo.h"

int main(int argc, char *argv[]) 
{
    Foo s;
    s.use();

    return 0;
}

为什么以及如何“正常”工作?

由于

编辑:我理解不完整的类型,但是当我可以使用unique_ptr而不使用new时会发生什么呢?

EDIT2:为我的问题更好地组织代码

4 个答案:

答案 0 :(得分:3)

简短的回答:它不起作用。

这个reference表示std::unique_ptr的默认构造函数创建一个空的唯一指针,这意味着它没有关联的对象。

此代码打印hello的原因是因为此声明

std::cout << "hello";

不需要任何Bar。它也可以是静态方法。也许编译器内联函数并用s.use()语句替换std::cout。但即使它确实调用了该方法,您也不会注意到任何错误,因为它根本不会访问Bar的内存。

对你的班级做一点改动,你会看到我的意思:

class Bar
{
public:
    Bar() : data(10) {};
    ~Bar() {};
    void print() {
        std::cout << "hello, data is: " << data;
    }

    int data;
};

现在,print访问无效内存,因为您从未调用new(甚至更好:make_unique)。它甚至可以工作并向控制台打印一些内容,但data的输出将是垃圾。如果你很幸运,应用程序将崩溃。

它似乎有效的另一个原因(感谢Stas):

std::unique_ptr定义operator->,它只返回包含的指针,但不检查指针是否指向有效内存。所以pteste->不会抛出异常。

答案 1 :(得分:1)

是的,此代码将“正常”向控制台打印“hello”,它与unique_ptr无关。您可以将std::unique_ptr<Bar> pteste替换为Bar* pteste中的Bar并获得相同的结果。

考虑如何调用pteste->print()

您可以将Bar::print()视为一个指向Bar对象的自由函数:

void print(Bar* this) {
    std::cout << "hello";
}

请注意,传递给print(Bar*)的指针永远不会被触及,所以理论上你可以传递任何你想要的东西(null,垃圾等),它会打印出“hello”到控制台。

答案 2 :(得分:0)

这是因为

std::unique_ptr<Bar> pteste;

是实例的指针声明,它不实例化指针,因此此时不需要知道有关Bar的详细信息(例如ctor)。

的情况下
Bar pteste

为了构造pteste,它需要知道定义,但由于Bar只是向前声明,因此会产生错误。

答案 3 :(得分:0)

所有指针都以相同的方式实现。即使你有指向不同类型的指针,通常都是int的大小。因此编译器在编译代码时不需要知道指针的类型。现在,如果你要取消引用那个将成为另一个故事的指针。即使您要初始化unique_ptr,也需要知道类型,因为new需要查看构造函数。

相关问题