我试图在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;
}
答案 0 :(得分:2)
您滥用inline
关键字。对它进行处理,好像它意味着“此函数的实现位于标题中”。
这会立即显示问题:您的某个cpp文件中有很多inline
个函数,这些函数不是标题。使用inline
函数的每个cpp文件 required 包含或包含该函数的定义。问题是链接器使用inline
函数执行神奇的操作,因为它们应该是许多cpp文件中的每一个的一个副本。因此编译器编译main.cpp
,并且(因为main不知道函数是内联的,所以注意稍后链接器应该在默认构造函数中链接)。编译器然后编译AccountReposity.cpp
,看到没有使用内联函数,所以只是跳过它。之后,链接器无法找到要使用的AccountRepository()
副本,并报告错误。如果正确地在头文件中定义了函数体,那么在编译步骤中,它将在到达链接阶段之前被实例化为main.cpp
。
某些编译器将inline
函数视为特殊的事实并不会真正影响经验法则。其他编译器不会对inline
函数进行任何特殊优化,并将其视为优化会导致您遇到的错误。忽略优化会使关键字的位置更加清晰。
答案 1 :(得分:0)
如果要将AccountRepository
的成员函数声明为inline
,则必须在使用它们的所有翻译单元中使用它们,如[basic.def.odr] / 3所示:
(...)内联函数应在每个使用它的翻译单元中定义。
从函数定义中删除inline
或将它们全部移到标题中。