c++ - 无法使用模板让此类工作吗?

标签 c++

我正在尝试使用通用对象在 C++ 中编写类似于 C# 接口(interface)的东西,但我无法让它工作。 每次我在 main 中创建一个新实例时,都会收到以下错误: 错误 1 ​​错误 LNK2019:无法解析的外部符号“public: __thiscall AccountRepository::AccountRepository(void)”

main.cpp

#include <iostream>
#include <stdio.h>
#include <string>
#include "AccountRepository.h"

using namespace std;

int main(){

    AccountRepository repo;

    return 0;
}

IRepository.h

#pragma once
#include <vector>
using namespace std;

template <class Entity>
class IRepository
{
public:
    virtual bool add(Entity entity) = 0;
    virtual bool update(Entity entity) = 0;
    virtual Entity getById(int Id) = 0;
    virtual bool remove(Entity entity) = 0;
    virtual vector<Entity> getAll() = 0;
};

AccountRepository.h

#pragma once
#include "IRepository.h"
#include "Account.h"
#include <vector>

class AccountRepository : public IRepository<Account>{
private:
    vector<Account> _accounts;

public:
    AccountRepository();
    ~AccountRepository();

    virtual bool add(Account entity) override;
    virtual bool update(Account entity) override;
    virtual Account getById(int Id) override;
    virtual bool remove(Account entity) override;
    virtual vector<Account> getAll() override;

};

AccountReposity.cpp

#include "AccountRepository.h"

inline AccountRepository::AccountRepository()
{

}

inline AccountRepository::~AccountRepository()
{

}

inline bool AccountRepository::add(Account entity)
{
    _accounts.push_back(entity);
    return true;
}

inline bool AccountRepository::update(Account entity)
{
    for (Account account : _accounts){
        if (account.getId() == entity.getId()){
            account.setName(entity.getName());
            account.setDescription(entity.getDescription());
            return true;
        }
    }

    return false;
}

inline Account AccountRepository::getById(int Id)
{
    for (Account account: _accounts)
    {
        if (account.getId() == Id)
            return account;
    }
}

inline bool AccountRepository::remove(Account entity)
{
    vector<Account>::iterator it;
    for (it = _accounts.begin(); it != _accounts.end(); ++it){
        if (it->getId() == entity.getId())
        {
            _accounts.erase(it);
            return true;
        }
    }

    return false;
}

inline vector<Account> AccountRepository::getAll()
{
    return _accounts;
}

最佳答案

您误用了 inline 关键字。将其视为“此函数的实现位于 header 中”。

这立即暴露了问题:您的一个 cpp 文件中有很多内联函数,这些函数不是 header 。每个使用内联函数的 cpp 文件都需要包含该函数的定义。问题在于链接器使用内联函数做了一些神奇的事情,因为它们应该是许多 cpp 文件中每个文件的一个拷贝。因此编译器编译 main.cpp,并且(因为 main 不知道该函数是内联的,请注意稍后链接器应该链接到默认构造函数中)。然后编译器编译AccountReposity.cpp,发现没有使用内联函数,因此跳过它。随后,链接器无法找到要使用的 AccountRepository() 拷贝,并报告错误。如果函数体在 header 中正确定义,则在进入链接阶段之前,它会在编译步骤中实例化到 main.cpp 中。

某些编译器将内联函数视为特殊的事实根本不会真正影响经验法则。其他编译器不会为内联函数提供任何特殊的优化,并且将其视为优化会导致您遇到的错误。忽略优化可以让关键字的去向更加清晰。

关于c++ - 无法使用模板让此类工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29660706/

相关文章:

c++ - 为什么 clang 在每次使用时都取消引用参数?

c++ - "invalid comparator": error when overloading the "<" operator

c++ - 带有 std::string 的文字类仅适用于模板特化?

c++ - 同时使用非原子和原子操作

c++ - 默认多个参数

c++ - memcpy/memmove 到 union 成员,这是否设置了 'active' 成员?

c++ - Cin 在循环的第一次迭代后无法执行

c++ - 理解指向函数的指针的问题

python - 使用调用策略创建属性 - boost::python

android - 如何从 Android Studio 调用 C++ 源代码?