rra*_*jik 0 c++ pointers object-lifetime undefined-behavior unique-ptr
#include <iostream>
#include <memory>
class Base
{
public:
virtual void foo() = 0;
};
class Derived : public Base
{
public:
void foo() override { std::cout << "Derived" << std::endl; }
};
class Concrete
{
public:
void Bar() { std::cout << "concrete" << std::endl; }
};
int main()
{
std::unique_ptr<Concrete> ConcretePtr = nullptr;
ConcretePtr->Bar();
std::unique_ptr<Base> BasePtr;
BasePtr->foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我假设将一个unique_ptr声明为具体类型Concrete
,为类型的对象分配内存,Concrete
而unique_ptr开始指向它.我的假设/理解是否正确?我问,因为ConcretePtr->Bar();
打印机"混凝土"到控制台.但是,如果我创建一个指向接口的唯一指针Base
,它不知道我需要的确切对象类型,也不知道在内存中分配/获取资源.
这失败BasePtr->foo();
了BasePtr._Mypair._Myval2 was nullptr.
为什么第一个声明std::unique_ptr<Concrete> ConcretePtr = nullptr;
自己分配一个对象?如果我不希望它指向那一行代码中的某个真实对象,但只想要一个智能指针呢?
现在,如果我将声明更改为std::unique_ptr<Concrete> ConcretePtr;
以及Concrete
类型如下,
class Concrete
{
int ConcreteNum;
public:
void Bar()
{
std::cout << "concrete" << std::endl;
ConcreteNum = 38;
std::cout << ConcreteNum << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
它没有ConcreteNum = 38;
抱怨那this
是nullptr
; 如果这this
就是nullptr
为什么以及之前的呼叫(哪里Concrete
没有任何状态ConcreteNum
)如何Bar
工作?
而且为什么它不会失败ConcretePtr->Bar();
(这->
需要一个具体的对象,不是吗?this
这里有什么?)但是在内部Bar
,在那个任务中?
我也看到同样的问题std::shared_ptr
.我不太确定声明,初始化和赋值之间的区别.请帮我理解.
我正在使用MSVC.
该unique_ptr
模型的指针.也就是说,它是指向另一个对象的对象.
初始化unique_ptr
with nullptr会在未指向或拥有另一个对象的状态下创建它.
这就像说Concrete* p = nullptr
.
以下列方式之一初始化它:
std::unique_ptr<Concrete> p{new Concrete()};
Run Code Online (Sandbox Code Playgroud)
要么
std::unique_ptr<Concrete> p; // = nullptr is implied.
p.reset(new Concrete());
Run Code Online (Sandbox Code Playgroud)
或更好:
std::unique_ptr<Concrete> p = std::make_unique<Concrete>();
Run Code Online (Sandbox Code Playgroud)
或者干脆:
auto p = std::make_unique<Concrete>();
Run Code Online (Sandbox Code Playgroud)
但是在这种情况下要小心,如果你真的想要指向Base接口:
std::unique_ptr<Base> p = std::make_unique<Derived>();
Run Code Online (Sandbox Code Playgroud)
要么
std::unique_ptr<Base> p = nullptr;
p = std::make_unique<Derived>(); // assignment from rvalue ref of compatible unique_ptr.
Run Code Online (Sandbox Code Playgroud)