gpt4 book ai didi

c++ - 动态选择类中私有(private)成员的类型

转载 作者:行者123 更新时间:2023-11-30 04:55:09 25 4
gpt4 key购买 nike

我无法理解:我有一个名为 MyClass 的类,它有一个 MyUsedClass 类型的私有(private)成员。为了创建单元测试,我有一个模拟(模拟)版本的 MyUsedClass。我想使用 MyUsedClass 的模拟私有(private)成员或 MyUsedClass 的真实私有(private)成员动态调用 MyClass。因为我想动态调用它,所以使用#defines 和#ifdefs 是行不通的。

基本上我想做这样的事情:

class MyClass {
public:
MyClass(bool mock = false) {}; // Default bool to false.
~MyClass(void) {};
void DoSomething(void) { /* Do something with MyUsedObject here... */ };
void DoMore(void);
...
private:
if (mock) {
MyUsedClassMock MyUsedObject;
} else {
MyUsedClassReal MyUsedObject;
}
};

MyClass MyObject; // Create default instance with real MyUsedObject.
MyClass MyObject(true); // Create instance with the mock MyUsedObject.

但这当然行不通,因为不能在类的定义中使用 if 语句。

另一种方法是使用多态性并创建一个基类、一个真实类和一个模拟类。基类将具有所有函数的所有实现,并且通过选择调用 MyClass 的真实版本或模拟版本,我可以选择 MyUsedObject 的类型。

class MyClassBase {
public:
MyClassBase(void) {};
~MyClassBase(void) {};
void DoSomething(void) { /* Do something with MyUsedObject here... */ };
void DoMore(void);
...
private:
// No MyUsedObject in the Base class.
};

class MyClassReal : public MyClassBase {
public:
MyClassReal(void) {};
~MyClassReal(void) {};
private:
MyUsedClassReal MyUsedObject; // Here is MyUsedObject created, but then "Real".
};

class MyClassMock : public MyClassBase {
public:
MyClassMock(void) {};
~MyClassMock(void) {};
private:
MyUsedClassMock MyUsedObject; // Here is MyUsedObject created, but then "Mock".
};

MyClassReal MyObject; // Create instance with the real MyUsedObject.
MyClassMock MyObject; // Create instance with the mock MyUsedObject.

不幸的是,这也不起作用,因为 MyClassBase 函数实现还不知道任何关于 MyUsedObject 的信息,所以我在这里遇到错误。一个想法是在基类中创建一个虚拟的 MyUsedObject,但这里的问题是基类还不知道对象的类型(真实的或模拟的)。此外,数据声明中不允许使用“虚拟”,所以无论如何,一旦我尝试了,我又会遇到更多错误。

我在这里错过了什么?

最佳答案

多态方法是可行的方法。但是,您必须想出不同的办法:

class MyUsedClass { }; // the base class, having (pure?) virtual functions
class MyUsedClassReal : public MyUsedClass { }; // provides real functionality
class MyUsedClassMock : public MyUsedClass { }; // mocks the functionality

派生类将提供实际场景和模拟时特别需要的实现。您自己的类现在可以动态地使用其中一个:

class MyClass
{
public:
MyClass(bool mock = false)
~MyClass(void) {};
void doSomething();
private:
std::unique_ptr<MyUsedClass> myUsedObject;
};

MyClass::MyClass(bool mock)
: myUsedObject(mock ? new MyUsedClassMock() : new MyUsedClassReal())
{ }

void MyClass::doSomething() { /* use the pointer! */ };

如果您遵循 StoryTeller 的提示(“依赖注入(inject)”),您会将对象作为参数传递给构造函数而不是在其中创建它,这可能是更可取的:

MyClass::MyClass(std::unique_ptr<MyUsedClass> object)
: myUsedObject(std::move(object))
{ }

还有一个 std::unique_ptr 作为参数,显然 MyClass 将获取所提供对象的所有权(是它的接收器);这适用于您的示例,而不是“始终执行”规则,它取决于用例,在其他情况下,共享指针(成员和参数)可能更合适。

关于c++ - 动态选择类中私有(private)成员的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53208134/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com