假设,我想创建一个带有指向另一个类 A
的指针的类 B
。在 A
的构造函数中,我想构造 B
并向其传递一个指向 this
的指针。原则上,这个指针可以是一个shared_ptr
,对吗?那么如何在构造函数中分配 shared_ptr
来创建这样一个类呢?
我在下面的代码中尝试过。 ClassB
和 ClassC
是相同的,都有一个指向 ClassA
的指针,它构造 ClassB
和 ClassC< 的实例
。唯一的两个区别是,ClassB
持有一个常规指针,而 ClassC
持有一个指向 ClassA
的 shared_ptr
,并且代码使用 ClassB
可以正常工作,而使用 ClassC
则不行。我做错了什么?
// Main.cpp : Defines the entry point for the console application.
#include "ClassA.h"
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Create B and C separately, without a reference to A:" << std::endl;
ClassB(nullptr);
ClassC(nullptr);
std::cout << "Create A, and through it B and C:" << std::endl;
ClassA A;
A.PrintHello();
A.getObjectB().getPointerToA()->PrintHello();
A.PrintHello();
A.getObjectC().getPointerToA()->PrintHello();
return 0;
}
// ClassA.h
#pragma once
#include "ClassB.h"
#include "ClassC.h"
class ClassA
{
private:
ClassB objectB;
ClassC objectC;
public:
ClassA(void);
ClassB getObjectB() { return objectB; };
ClassC getObjectC() { return objectC; };
void PrintHello();
};
// ClassA.cpp
#include "ClassA.h"
#include <iostream>
#include <memory>
ClassA::ClassA(void) : objectB(ClassB( this )), objectC(ClassC( std::make_shared<ClassA>(*this) ))
{
std::cout << "Class A fully constructed" << std::endl;
}
void ClassA::PrintHello()
{
std::cout << "Hello" << std::endl;
}
// ClassB.h
#pragma once
#include <memory>
class ClassA;
class ClassB
{
private:
ClassA* pointerToA;
public:
ClassB(ClassA* pA);
ClassA* getPointerToA() { return pointerToA; };
};
// ClassB.cpp
#include "ClassB.h"
#include <iostream>
ClassB::ClassB(ClassA* pA) : pointerToA(pA)
{
std::cout << "Class B constructed" << std::endl;
}
// ClassC.h
#pragma once
#include <memory>
class ClassA;
class ClassC
{
private:
std::shared_ptr<ClassA> pointerToA;
public:
ClassC(std::shared_ptr<ClassA> pA);
std::shared_ptr<ClassA> getPointerToA() { return pointerToA; };
};
// ClassC.cpp
#include "ClassC.h"
#include <iostream>
ClassC::ClassC(std::shared_ptr<ClassA> pA) : pointerToA(pA)
{
std::cout << "Class C constructed" << std::endl;
}
最佳答案
它们做的不是同一件事:
ClassA::ClassA(void) : objectB(ClassB( this )), objectC(ClassC( std::make_shared<ClassA>(*this) ))
第一个初始化程序使用 this
指针创建一个 ClassB
类型的临时对象,并通过复制该临时对象来初始化 objectB
:
objectB(ClassB( this ))
第二个创建一个new ClassA
作为*this
的拷贝,将其存储在shared_ptr
中,然后用该 shared_ptr
初始化一个临时 ClassC
,然后通过复制该临时值来初始化 objectC
:
objectC(ClassC( std::make_shared<ClassA>(*this) ))
您的语法不必要地冗长,避免临时变量和拷贝并直接初始化您的成员:
objectB( this ), objectC( std::make_shared<ClassA>(*this) )
这相当于:
objectB( this ), objectC( std::shared_ptr<ClassA>( new ClassA(*this) ) )
应该清楚的是,objectB
有一个指向 this
的指针,但 objectB
有一个指向不同<的(共享)指针/em> 对象,即 *this
的拷贝。
shared_ptr 的要点是它拥有您给它的指针,并且(通常)会删除该指针。在对象的构造函数中不能有一个拥有 this
的 shared_ptr
,因为在该对象完成构造之前,它不能被任何 shared_ptr
(您给 shared_ptr
的指针是一个指向完整对象的指针,而不是通过其构造函数部分构造的指针),因此没有安全的方法获取一个引用 this
的 shared_ptr
,您可以将其传递给 objectC
的构造函数。有一种方法可以做到这一点,使用 shared_ptr
的别名功能,但我认为您应该重新检查您的设计并询问为什么您想要 objectC
>“拥有”它所属的对象......这是没有意义的。
关于c++ - 构造一个以 shared_ptr 作为成员字段的类的正确语法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11192016/