c++ - 模拟复制构造函数的 C++ 类
问题描述
我从 C# 转向 C++,当我尝试构建测试时,复制构造函数让我很难以我习惯的方式模拟。
#include <iostream>
using namespace std;
class DB {
public:
virtual int getValue() { return 42; }
DB(const DB& source) { }
DB() { }
};
class DB_Mock: public DB {
public:
virtual int getValue() { return 999; }
};
class A {
public:
A(DB db) {
m_db = db;
}
void doIt() {
cout << "Result:" << m_db.getValue() << endl;
}
private:
DB m_db;
};
int main() {
/* prints 42 as expected */
DB db;
A a(db);
a.doIt();
/* prints 42, expected 999 */
DB_Mock db_mock;
A a2(db_mock);
a2.doIt();
return 0;
}
你如何处理这样的问题?
解决方案
m_db 不是引用或指针,c++ 多态性仅适用于基类指针或引用。
A(DB db) {
m_db = db; // m_db just sliced copy of base part of db.
}
将此更改为参考
class A
{
public:
explicit A(DB &db) : m_db(db) // it is initializing not copy
{
}
void doIt()
{
std::cout << "Result:" << m_db.getValue() << std::endl;
}
private:
DB &m_db; // Now m_db is reference
};
以上将起作用但是,如果要更改使用智能指针,则不能更改参考值[推荐]。
参考 :
- 构造函数和成员初始化列表
- 智能指针
- 覆盖
- 查看虚拟表了解 v_ptr
编辑:
正如皮特贝克尔所说,要注意生命周期,如果你传递局部变量引用,比如
A make()
{
DB db;
A a(db);
return a;
}
int main()
{
const A &a = make();
// Wrong db is destroyed (dangling reference).
a.doIt(); // assume doIt(), getValue() are declared as const
return 0;
}
上面的代码是错误的(未定义的行为),所以我建议使用智能指针(堆存储)来避免这个问题。
谢谢。
推荐阅读
- python - 从资源管理器中选择一个文件并将他的名字插入 python kivy 应用程序
- linux - 如何构建带有-generic 后缀的linux内核?
- matlab - Matlab上两个符号数组的卷积
- google-bigquery - Bigquery DR 投诉和多区域支持
- java - 筹码的额外结束和开始保证金
- php - 如何对前缀中包含当前年份的数字进行排序
- laravel - 为什么用户凭据在我的登录单元测试中不起作用?
- vue.js - 无法使用“import * as name from './module', webpack 在 Vue 中返回错误
- django - TweepError at / Unable to access file: No such file or directory when I use can
- typescript - 如何在 Typescript 中使用 Ghost 的 api 从异步函数中获取对象属性