[英]Storing and using smart_ptr address
我正在嘗試將shared_ptr
傳遞給周圍的 object,它可能是也可能不是 null:
#include <iostream>
#include <memory>
struct MyObject {
int i = 0;
MyObject(const int i_) : i(i_) {}
};
struct Command {
std::shared_ptr<MyObject> cmdObj;
Command(std::shared_ptr<MyObject>& obj) : cmdObj(obj) {
std::cout << "Store and use this address: " << &obj << std::endl; // [1]
}
void execute() {
if (cmdObj == nullptr) {
cmdObj = std::make_shared<MyObject>(42);
} else {
cmdObj->i = 7;
}
}
};
struct CommandManager {
std::shared_ptr<MyObject> globalObj; // [1]
CommandManager() { globalObj = nullptr; }
void runCommand() {
Command cmd(globalObj);
cmd.execute();
}
};
int main() {
CommandManager cm;
std::cout << "cm.globalObj address: " << &cm.globalObj << std::endl; // [1]
cm.runCommand();
if (cm.globalObj == nullptr) {
std::cout << "globalObj is null" << std::endl;
} else {
std::cout << "globalObj is " << cm.globalObj->i << std::endl;
}
}
如您所見,我正在嘗試從Command
中操縱或創建globalObj
。 但是,盡管在構造函數 ( [1]
) 中傳遞了地址,但我沒有正確存儲它,因此新的 object 在CommandManager
中可用。
我該怎么做才能正確存儲和使用shared_ptr<MyObject>
的地址?
先感謝您。
要存儲地址,您需要一個指針。 在這種情況下,指向 std::shared_ptr 的指針。
struct Command {
std::shared_ptr<MyObject>* cmdObj;
Command(std::shared_ptr<MyObject>& obj) : cmdObj(&obj) {
std::cout << "Store and use this address: " << &obj << std::endl; // [1]
}
void execute() {
if (*cmdObj == nullptr) {
*cmdObj = std::make_shared<MyObject>(42);
} else {
(*cmdObj)->i = 7;
}
}
};
您也可以在此處使用引用,因為您需要將某些內容傳遞給Command
的構造函數,並且您不會遇到懸空引用問題,除非您在使用前一個選項時遇到懸空指針問題。
struct Command {
std::shared_ptr<MyObject>& cmdObj;
Command(std::shared_ptr<MyObject>& obj) : cmdObj(obj) {
std::cout << "Store and use this address: " << &obj << std::endl; // [1]
}
void execute() {
if (cmdObj == nullptr) {
cmdObj = std::make_shared<MyObject>(42);
} else {
cmdObj->i = 7;
}
}
};
但是,我不確定您是否真的想要一個std::shared_ptr
開頭。 一個簡單的變量也可以。
struct Command {
MyObject* cmdObj;
Command(MyObject* obj) : cmdObj(obj) {
std::cout << "Store and use this address: " << obj << std::endl; // [1]
}
void execute() {
cmdObj->i = 7;
}
};
struct CommandManager {
MyObject globalObj = 42; // [1]
void runCommand() {
Command cmd(&globalObj);
cmd.execute();
}
};
int main() {
CommandManager cm;
std::cout << "cm.globalObj address: " << &cm.globalObj << std::endl; // [1]
cm.runCommand();
std::cout << "globalObj is " << cm.globalObj.i << std::endl;
}
如果您的初衷是通過std::shared_ptr
共享MyObject
object,那么您需要先創建該 object,然后才能共享它。
struct Command {
std::shared_ptr<MyObject> cmdObj;
Command(std::shared_ptr<MyObject>& obj) : cmdObj(obj) {
}
void execute() {
cmdObj->i = 7;
}
};
struct CommandManager {
std::shared_ptr<MyObject> globalObj; // [1]
CommandManager() { globalObj = std::make_shared<MyObject>(42); }
void runCommand() {
Command cmd(globalObj);
cmd.execute();
}
};
或者您可以在Command
中創建它,然后與CommandManager
共享。
struct Command {
std::shared_ptr<MyObject> cmdObj;
Command(std::shared_ptr<MyObject>& obj) {
if (obj == nullptr) {
obj = std::make_shared<MyObject>(42);
}
cmdObj = obj;
}
void execute() {
cmdObj->i = 7;
}
};
或者,您可以創建一個std::unique_ptr
並共享它,然后在需要時在Command
中創建MyObject
object。
struct Command {
std::shared_ptr<std::unique_ptr<MyObject>> cmdObj;
Command(std::shared_ptr<std::unique_ptr<MyObject>> obj) : cmdObj(obj) {
}
void execute() {
if (*cmdObj == nullptr) {
*cmdObj = std::make_unique<MyObject>(42);
} else {
(*cmdObj)->i = 7;
}
}
};
struct CommandManager {
std::shared_ptr<std::unique_ptr<MyObject>> globalObj; // [1]
CommandManager() { globalObj = std::make_shared<std::unique_ptr<MyObject>>(nullptr); }
void runCommand() {
Command cmd(globalObj);
cmd.execute();
}
};
注意:引用不是地址,盡管使用與地址運算符相同的&
字符。 我假設您是在談論參考,而不是地址。
您將globalObj
引用傳遞給構造函數,但是唯一的引用是形式參數obj
。
您打印obj
的地址並驗證它是否與預期的globalObj
地址相同。 但是cmdObj
不是obj
。
cmdObj
是 object,不是參考。 初始化它將創建您初始化它的任何內容的副本,與原始文件完全斷開鏈接。 它的地址是不同的,你可以打印出來自己看看。
更改cmdObj
(副本)不會以任何方式、形狀或形式影響globalObj
(原始)。
if (cmdObj == nullptr) {
// Before the assignment, globalObj was nullptr.
cmdObj = std::make_shared<MyObject>(42);
// And it still is after the assignment to cmdObj.
您也可以將cmdObj
作為參考:
Mystd::shared_ptr<MyObject>Object*& cmdObj;
這可能會產生您想要的效果。
請注意,我不是在談論任何這些智能指針指向的對象。 只是指針本身。
顯示shared_ptr
生命周期和它們指向的 object 生命周期之間差異的最小程序。
#include <iostream>
#include <memory>
int main() {
// Create an integer, give shared ownership to sp_1
std::shared_ptr<int> sp_1 = std::make_shared<int>(2);
// sp_2 points to same integer now, so sp_2.get() == sp_1.get().
// Reference count is increased to 2.
// Note that sp_1 and sp_2 are still different objects, i.e. &sp_2 != &sp_1
std::shared_ptr<int> sp_2 = sp_1;
// Value of int is changed (both sp_1 and sp_2 point to it)
*sp_2 = 4;
// Replace shared_ptr object sp_2. It now points to another integer object.
// sp_1 is not affected by it, the reference count to the first integer is back down to 1.
sp_2 = std::make_shared<int>(6);
std::cout << *sp_1 << " is still 4!" << std::endl;
std::cout << *sp_2 << " is 6!" << std::endl;
// "Destroy" first integer object
sp_1.reset();
// This is perfectly valid since sp_2 is pointing to a different integer
*sp_2 = 8;
std::cout << *sp_2 << " is 8!" << std::endl;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.