“预定义”和使用命名空间和 std::shared_ptr 的正确方法是啥?
Posted
技术标签:
【中文标题】“预定义”和使用命名空间和 std::shared_ptr 的正确方法是啥?【英文标题】:What is the correct way to "predefine" and use namespaces and std::shared_ptr?“预定义”和使用命名空间和 std::shared_ptr 的正确方法是什么? 【发布时间】:2013-02-28 18:02:45 【问题描述】:我一直很难找到类似这个问题的东西,所以我会在这里问。
我有一个包含十几个源/头文件的项目。我遇到的主要问题是预定义我在命名空间中创建的类。代码如下:
“GlobalIncludes.h”
/*include dependencies and library headers...*/
/*[Note 1]How would I predefine the classes inside namespaces?*/
typedef std::tr1::shared_ptr<Class1> ClassPtr1;//[Note 2]
typedef std::tr1::shared_ptr<Class2> ClassPtr2;//[Note 2]
/*[Note 2]What is the correct way to predefine the shared_ptr's?*/
#include "Class1.h"
#include "Class2.h"
“Class1.h”
namespace myNamespace
class Class1
/*variables and functions*/
void doSomething(...);
Class2 exampleObject;
;
“Class2.h”
namespace myNamespace
class Class2
/*variables and functions*/
;
如果这听起来有点令人困惑,我提前道歉......
基本上我想知道是否可以预定义namespace myNamespace
中的类,同时声明shared_ptr
。如果这是可能的,我将如何做到这一点并在源代码中正确使用它们?
【问题讨论】:
不要预定义任何东西,它只会让你的代码不那么可读。通过使用命名空间说明符,每个人都可以准确地知道您的类型是什么,而无需费力地阅读其他代码。 (但这只是我的看法) 【参考方案1】:如果您希望类型定义与类属于同一命名空间的一部分(我建议):
namespace my_namespace
class Class1;
class Class2;
typedef std::tr1::shared_ptr<Class1> ClassPtr1;
typedef std::tr1::shared_ptr<Class2> ClassPtr2;
#include "Class1.h"
#include "Class2.h"
否则,如果您希望指针类型定义成为全局命名空间的一部分
namespace my_namespace
class Class1;
class Class2;
typedef std::tr1::shared_ptr<my_namespace::Class1> ClassPtr1;
typedef std::tr1::shared_ptr<my_namespace::Class2> ClassPtr2;
#include "Class1.h"
#include "Class2.h"
可能,您可以使用宏(相同的命名空间)使事情更紧凑:
#define DECLARE_PTR_ALIAS(N, C, P) \
namespace N class C;
typedef std::tr1::shared_ptr<C> P; \
或者(不同的命名空间):
#define DECLARE_PTR_ALIAS(N, C, P) \
namespace N class C; \
typedef std::tr1::shared_ptr<N::C> P;
这样可以更简单地为多个类定义指针别名:
DECLARE_PTR_ALIAS(my_namespace, Class1, ClassPtr1)
DECLARE_PTR_ALIAS(my_namespace, Class2, ClassPtr2)
...
【讨论】:
感谢您快速详细的回复!我正在对此进行测试以查看结果。 通过一些快速测试,我能够比我自己更成功地使用它。非常感谢 :D 编辑:我也很喜欢通过#define
更有条理的方法。我已经在使用它,但我认为它不会那样工作。
@Molma:好的,很高兴它有帮助:-)【参考方案2】:
要在命名空间中预先声明类(或函数等),请执行以下操作:
namespace myNamespace
class myClassA;
class myClassB;
如果我只是预先声明一个类,我喜欢把它放在一行:(只是个人喜好)
namespace myNamespace class myClassA;
但是,在您的示例中,Class1 已经在命名空间中,因此您不妨这样做:
namespace myNamespace
class Class2;
class Class1
/*variables and functions*/
void doSomething(...);
Class2 exampleObject;
;
唯一的问题是 Class1 有 Class2 作为成员变量。您不能使用预先声明的对象作为成员,因为编译器需要知道对象的大小才能将其嵌入到类中。您只能将预先声明的对象用作引用或指针,因为它们具有固定的大小。
如果您将 Class2 设为智能指针,那么您可以这样做:
namespace myNamespace
class Class2;
typedef std::shared_ptr<Class2> Class2ptr;
class Class1
/*variables and functions*/
void doSomething(...);
Class2ptr exampleObject;
;
但是 shared_ptr 必须完全包含并且不能预先声明,因为 shared_ptr 现在是成员变量,并且类需要知道它们的完整大小。
【讨论】:
以上是关于“预定义”和使用命名空间和 std::shared_ptr 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
使用相同的函数但重载不同的 std::tr1::shared_ptr<T> 和 std::shared_ptr<T>
std::mutex 和 std::shared_mutex 之间的区别
我可以在 std::shared_mutex 上使用 std::shared_lock 更改数据吗?
这是 std::vector 和 std::shared_ptr 内存泄漏的错误吗?
`std::optional` 比 `std::shared_ptr` 和 `std::unique_ptr` 有啥优势?