2

假设,我想创建一个B带有指向另一个类的指针的类A。在A我想构造的构造函数中B,并传递一个指向this. 原则上,这个指针可以是 a shared_ptr,对吗?那么如何shared_ptr通过构造函数中的赋值来创建这样的类呢?

我在下面的代码中尝试过。ClassBClassC是相同的,带有一个指向ClassA它的构造ClassB和实例的指针ClassC。唯一的两个区别是ClassB持有一个常规指针并ClassC持有一个shared_ptrto ClassA,以及带有的代码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;
}
4

2 回答 2

4

这些不是做同样的事情:

ClassA::ClassA(void) : objectB(ClassB( this )), objectC(ClassC( std::make_shared<ClassA>(*this) ))

第一个初始化器ClassB使用this指针创建一个临时类型,并objectB通过复制该临时来进行初始化:

objectB(ClassB( this ))

第二个创建一个new ClassA作为 的副本*this,将其存储在 a 中,然后用 thatshared_ptr初始化一个临时文件,然后通过复制该临时文件进行初始化:ClassCshared_ptrobjectC

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有一个指向thisobjectB有一个(共享)指向不同对象的指针,即*this.

a 的要点shared_ptr是它拥有您给它的指针,并且(通常)会删除该指针。您不能在对象的构造函数shared_ptr中拥有a this,因为在对象完成构造之前,它不能被任何人拥有shared_ptr(您给 ashared_ptr的指针是指向完整对象的指针,而不是部分构造的一半通过它的构造函数),所以没有安全的方法来获得可以传递给构造函数的shared_ptr引用。有一种方法可以做到这一点,使用 的别名功能,但我认为您应该重新检查您的设计并询问为什么要“拥有”它所属的对象......这没有意义。thisobjectCshared_ptrobjectC

于 2012-06-25T17:47:11.620 回答
1

std::make_shared分配并初始化一个新对象。

于 2012-06-25T15:56:49.840 回答