无法让这个带有模板的类工作?

Can't get this class with template to work?

本文关键字:工作      更新时间:2023-10-16

我正试图用一个通用对象在C++中编写类似C#接口的东西,但我无法实现。每次我在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关键字。将其视为"此函数的实现在标头中"。

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

某些编译器对inline函数进行特殊处理,这一事实根本不会影响经验法则。其他编译器不会对inline函数进行任何特殊的优化,将其视为优化会导致出现错误。忽略优化可以更清楚地显示关键字的位置。

如果您想将AccountRepository的成员函数声明为inline,您必须按照[basic.def.odr]/3:在所有使用它们的翻译单元中使它们为人所知

(…)内联函数应在使用它的每个翻译单元中定义。

从函数定义中删除inline,或者将它们全部移到标头中。