std::shared_ptr使用new和make_shared两种方法构造关于访问权限的区别

文章探讨了C++11中std::shared_ptr的构造方法在某些情况下无法使用make_shared的问题,尤其是在友元类中构造私有类实例时。作者通过实例展示了如何使用new操作并分析了可能的原因:std::make_shared不被视为友元函数,因此无法访问私有构造函数。
摘要由CSDN通过智能技术生成

std::shared_ptr的构造方法

C++11给开发者提供了十分好用的智能指针 std::shared_ptr ,合理的使用智能指针可以一定程度的避免内存泄漏问题。众所周知,C++11 为 std::shared_ptr 提供了两种构造方法,如下:

	std::shared_ptr<int> ptr1(new int(10));
	std::shared_ptr<int> ptr2 = std::make_shared<int>(10);

一般来说,这两个构造方法并无太大的区别,但我们更建议使用 make_shared 来创建智能指针,其在一些情况下效率更优。但今天开发时,遇到了无法使用 make_shared 而 new 操作正常的情况,本博客即记录该现象。

场景

假设一下这样的场景,我们需要一个 Clock 类和一个用于管理 Clock 对象的 ClockManager 类。我们希望 Clock 类只能由 ClockManager 来构建,所以将 Clock 的构造函数设置为 private ,并且将 ClockManager 设置为 Clock 的友元类, 同时 ClockManager 使用一个智能指针来管理类内的 Clock 对象。代码如下:

class ClockManager;

class Clock {
	friend ClockManager;
private:
	Clock() {};
};


class ClockManager {
public:
	ClockManager();
private:
	std::shared_ptr<Clock> clock;
};

接下来来编写 ClockManager 的构造函数,我们希望在构造函数中给 clock 分配内存,此时我们先使用 std::make_shared 来构造 clock 对象,完整代码如下:

#include <iostream>
#include <memory>

class ClockManager;

class Clock {
	friend ClockManager;
private:
	Clock() {};
};


class ClockManager {
public:
	ClockManager();
private:
	std::shared_ptr<Clock> clock;
};

ClockManager::ClockManager(){
	clock = std::make_shared<Clock>();
}

int main() {
	ClockManager clock;
	return 0;
}

尝试编译,发现报错:“Clock::Clock”: 无法访问 private 成员(在“Clock”类中声明)。
这个报错让我感到莫名其妙,我明明已经将 ClockManager 设置为 Clock 的友元类,但依旧不能在ClockManager 的成员函数中构造 Clock 对象,于是我尝试使用 new 来构造 Clock 对象,代码有区别的地方如下:

ClockManager::ClockManager() : clock(new Clock) {
}

这样便编译成功,无异常出现。
再看一个更加一般化的情况:

#include <iostream>
#include <memory>

class ClockManager;

class Clock {
	friend ClockManager;
private:
	Clock() {};
};


class ClockManager {
public:
	ClockManager();
};

ClockManager::ClockManager() {
	//std::shared_ptr<Clock> c1 = std::make_shared<Clock>(); //使用这一行无法通过编译
	std::shared_ptr<Clock> c2(new Clock);
}

int main() {
	ClockManager clock;
	return 0;
}

我的猜测是,因为 std::shared_ptr 并不是 ClockManager 的成员函数,而是 std 标准库的一部分,该函数并不像 ClockManager一样拥有 Clock 的访问权限,所以没办法访问 Clock 的构造函数来构造智能指针并返回。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值