强制仅在某些代码中使用的特定构造函数,而不是其他任何地方
force a specific constructor used solely in certain code, nowhere else
有时,我们需要提供一个特定的构造函数仅用于测试用途。我们怎么能强制这样的构造函数只在测试代码中使用,而不是在其他地方使用。我只是想知道这是否可以在 c++11/14 中实现。例如,
class A {
public:
A() = default; // used only in test code
}
class A_Test : public ::testing::Test {
private:
A a; // it is ok.
};
class A_Production {
private:
A a; // compiler error
}
我可以想象使用friend
装饰器并将特定的构造函数放在protected
中以限制访问。 但是在遗留代码中还有其他现有的朋友。是否可以制作一个自定义说明符,例如在 c++1x 中受保护?
有什么想法吗?
您可以使用密钥习惯用法:
您不是直接的友谊,而是通过 ConstructorKey
提供的间接寻址限制从A_Test
访问A
,A
在其界面中使用它希望ConstructorKey
的朋友访问。
class A {
class ConstructorKey {
friend class A_Test;
private:
ConstructorKey() {};
ConstructorKey(ConstructorKey const&) = default;
};
public:
// Whoever can provide a key has access:
explicit A(ConstructorKey); // Used only in test code
};
class A_Test : public ::testing::Test {
private:
A a {ConstructorKey{}}; // OK
};
class A_Production {
private:
A a {ConstructorKey{}}; // Compiler error
};
我可以想到几种方法来做到这一点。
-
使构造函数
protected
,只有测试子类使用它。 -
将前向声明添加到某个虚拟类,
class TestClassThatShouldNotBeUsedInProductionCode;
,然后声明一个构造函数,该构造函数将对此类的引用作为参数:A::A( /* other constructor arguments */, const TestClassThatShouldNotBeUsedInProductionCode &)
构造函数可以完全忽略此参数。你的测试模块可以定义这个虚拟的空类:class TestClassThatShouldNotBeUsedInProductionCode {};
,并能够使用它构造你的A
类。然后,只有您的测试模块才能使用此构造函数,并且它的名称非常清楚地表明了它的目的。实际上没有任何方法可以将某些翻译单元定义为"真实"代码与"测试"代码,C++,您只想实施一个很难意外违反的明确策略。
一些变体是可能的,例如使用内部类而不是向前声明独立类。内部类只能由测试代码实例化。
作为替代方法,在执行 A 测试的 cpp 文件中:
#define private public
#include "ClassA.h"
// ready for testing :)
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用dynamic_cast和构造函数时出错
- 在c++中使用向量时,如何调用构造函数和析构函数
- 奇怪的构造函数行为