首页 > 解决方案 > 模拟复制构造函数的 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;
}

你如何处理这样的问题?

标签: c++

解决方案


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
};

在这里编译并运行

以上将起作用但是,如果要更改使用智能指针,则不能更改参考值[推荐]。

参考 :

  1. 构造函数和成员初始化列表
  2. 智能指针
  3. 覆盖
  4. 查看虚拟表了解 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;
}

上面的代码是错误的(未定义的行为),所以我建议使用智能指针(堆存储)来避免这个问题。

谢谢。


推荐阅读