error LNK2005 --类的声明和定义放在一个文件中
刷C++primer的时候,将类的声明和定义均放在头文件中,报错error LNK2005
1> Sales_data.h
1>Sales_data.obj : error LNK2005: "public: class Sales_data & __thiscall Sales_data::operator+=(class Sales_data const &)" (??YSales_data@@QAEAAV0@ABV0@@Z) 已经在 main.obj 中定义
1>Sales_data.obj : error LNK2005: "class Sales_data __cdecl operator+(class Sales_data const &,class Sales_data const &)" (??H@YA?AVSales_data@@ABV0@0@Z) 已经在 main.obj 中定义
1>Debug\Sales_data.obj : warning LNK4042: 对象被多次指定;已忽略多余的指定
1>E:\C++Projects\PrimerCode\02\Debug\02.exe : fatal error LNK1169: 找到一个或多个多重定义的符号
1>
1>生成失败。
1>
原始代码:
Sales_data.h:
#include <iostream>
#include <string>
using namespace std;#ifndef SALES_DATA_H_INCLUDE
#define SALES_DATA_H_INCLUDEclass Sales_data{//友元函数
friend std::istream& operator >> (std::istream&,Sales_data&);
friend std::ostream& operator << (std::ostream&,const Sales_data&);
friend bool operator > (const Sales_data&,const Sales_data&);
friend bool operator < (const Sales_data&,const Sales_data&);
friend bool operator == (const Sales_data&,const Sales_data&);//构造函数
public:Sales_data() {};Sales_data(const std::string &book):bookNo(book){};Sales_data(std::istream &is){ is>>*this;};public:Sales_data& operator += (const Sales_data&);std::string isbn() const {return bookNo;};private:std::string bookNo;int units_sold;double sellingprice;double saleprice;double discount;};
//Sales_data operator + (const Sales_data&,const Sales_data&);inline std::istream& operator >> (std::istream& in ,Sales_data& s)
{in >> s.bookNo >> s.units_sold >> s.saleprice >> s.sellingprice;if(s.sellingprice != 0)s.discount = s.saleprice/s.sellingprice;elses = Sales_data();//输入错误,重置输入数据return in;
}inline std::ostream& operator << (std::ostream& out ,const Sales_data& s)
{out<<s.isbn() << " " << s.units_sold <<" " << s.saleprice <<" " << s.sellingprice ;return out;
}inline bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs)
{return lhs.isbn()==rhs.isbn();
}inline bool operator == (const Sales_data &lhs,const Sales_data& rhs)
{return lhs.bookNo == rhs.bookNo &&lhs.units_sold == rhs.units_sold &&lhs.sellingprice == rhs.sellingprice &&lhs.saleprice == rhs.saleprice;
}inline bool operator != (const Sales_data &lhs,const Sales_data & rhs)
{return !(lhs==rhs);
}Sales_data& Sales_data::operator += (const Sales_data& rhs)
{units_sold += rhs.units_sold;saleprice = (rhs.units_sold*rhs.saleprice+units_sold*saleprice)/(rhs.units_sold+units_sold);if(sellingprice!=0)discount = saleprice / sellingprice;return *this;
}Sales_data operator + (const Sales_data &lhs,const Sales_data &rhs)
{Sales_data ret(lhs);//把lhs的内容拷贝到临时变量ret中,这种做法便于运算ret+=rhs;return ret;
}#endif
解决办法:
一、将这两个函数使用inline的形式在头文件中定义
二、将类的声明和定义分开放,声明放在头文件,定义放在源文件
一、将这两个函数使用inline的形式在头文件中定义
Sales_data.h
#include <iostream>
#include <string>
using namespace std;#ifndef SALES_DATA_H_INCLUDE
#define SALES_DATA_H_INCLUDEclass Sales_data{//友元函数
friend std::istream& operator >> (std::istream&,Sales_data&);
friend std::ostream& operator << (std::ostream&,const Sales_data&);
friend bool operator > (const Sales_data&,const Sales_data&);
friend bool operator < (const Sales_data&,const Sales_data&);
friend bool operator == (const Sales_data&,const Sales_data&);//构造函数
public:Sales_data() {};Sales_data(const std::string &book):bookNo(book){};Sales_data(std::istream &is){ is>>*this;};public:Sales_data& operator += (const Sales_data&);std::string isbn() const {return bookNo;};private:std::string bookNo;int units_sold;double sellingprice;double saleprice;double discount;};
//Sales_data operator + (const Sales_data&,const Sales_data&);inline std::istream& operator >> (std::istream& in ,Sales_data& s)
{in >> s.bookNo >> s.units_sold >> s.saleprice >> s.sellingprice;if(s.sellingprice != 0)s.discount = s.saleprice/s.sellingprice;elses = Sales_data();//输入错误,重置输入数据return in;
}inline std::ostream& operator << (std::ostream& out ,const Sales_data& s)
{out<<s.isbn() << " " << s.units_sold <<" " << s.saleprice <<" " << s.sellingprice ;return out;
}inline bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs)
{return lhs.isbn()==rhs.isbn();
}inline bool operator == (const Sales_data &lhs,const Sales_data& rhs)
{return lhs.bookNo == rhs.bookNo &&lhs.units_sold == rhs.units_sold &&lhs.sellingprice == rhs.sellingprice &&lhs.saleprice == rhs.saleprice;
}inline bool operator != (const Sales_data &lhs,const Sales_data & rhs)
{return !(lhs==rhs);
}inline Sales_data& Sales_data::operator += (const Sales_data& rhs)
{units_sold += rhs.units_sold;saleprice = (rhs.units_sold*rhs.saleprice+units_sold*saleprice)/(rhs.units_sold+units_sold);if(sellingprice!=0)discount = saleprice / sellingprice;return *this;
}inline Sales_data operator + (const Sales_data &lhs,const Sales_data &rhs)
{Sales_data ret(lhs);//把lhs的内容拷贝到临时变量ret中,这种做法便于运算ret+=rhs;return ret;
}#endif
二、将类的声明和定义分开放,声明放在头文件,定义放在源文件
Sales_data.h
#include <iostream>
#include <string>
using namespace std;#ifndef SALES_DATA_H_INCLUDE
#define SALES_DATA_H_INCLUDEclass Sales_data{//友元函数
friend std::istream& operator >> (std::istream&,Sales_data&);
friend std::ostream& operator << (std::ostream&,const Sales_data&);
friend bool operator > (const Sales_data&,const Sales_data&);
friend bool operator < (const Sales_data&,const Sales_data&);
friend bool operator == (const Sales_data&,const Sales_data&);//构造函数
public:Sales_data() {};Sales_data(const std::string &book):bookNo(book){};Sales_data(std::istream &is){ is>>*this;};public:Sales_data& operator += (const Sales_data&);std::string isbn() const {return bookNo;};private:std::string bookNo;int units_sold;double sellingprice;double saleprice;double discount;};
Sales_data operator + (const Sales_data&,const Sales_data&);#endif
Sales_data.cpp
#include "Sales_data.h"
inline std::istream& operator >> (std::istream& in ,Sales_data& s)
{in >> s.bookNo >> s.units_sold >> s.saleprice >> s.sellingprice;if(s.sellingprice != 0)s.discount = s.saleprice/s.sellingprice;elses = Sales_data();//输入错误,重置输入数据return in;
}inline std::ostream& operator << (std::ostream& out ,const Sales_data& s)
{out<<s.isbn() << " " << s.units_sold <<" " << s.saleprice <<" " << s.sellingprice ;return out;
}inline bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs)
{return lhs.isbn()==rhs.isbn();
}inline bool operator == (const Sales_data &lhs,const Sales_data& rhs)
{return lhs.bookNo == rhs.bookNo &&lhs.units_sold == rhs.units_sold &&lhs.sellingprice == rhs.sellingprice &&lhs.saleprice == rhs.saleprice;
}inline bool operator != (const Sales_data &lhs,const Sales_data & rhs)
{return !(lhs==rhs);
}Sales_data& Sales_data::operator += (const Sales_data& rhs)
{units_sold += rhs.units_sold;saleprice = (rhs.units_sold*rhs.saleprice+units_sold*saleprice)/(rhs.units_sold+units_sold);if(sellingprice!=0)discount = saleprice / sellingprice;return *this;
}Sales_data operator + (const Sales_data &lhs,const Sales_data &rhs)
{Sales_data ret(lhs);//把lhs的内容拷贝到临时变量ret中,这种做法便于运算ret+=rhs;return ret;
}
error LNK2005 --类的声明和定义放在一个文件中相关推荐
- 将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中
将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中 写这种.h和.cpp文件分开的大程序,虽然对很多人来说很简单,对自己来说算是第一次吧,好好学C++,加油~ 题目:定义Point类,由 ...
- 函数声明放在头文件中,函数的定义放在实现文件中,然后在主函数中调用
1.文件的组织结构如下图: 2.Menu.h内容如下: #ifndef MENU_H #define MENU_H int add(int a,int b); int minus(int a, int ...
- C++ : 编译单元、声明和定义、头文件作用、防止头文件在同一个编译单元重复引用、static和不具名空间...
转 自:http://www.cnblogs.com/rocketfan/archive/2009/10/02/1577361.html 1. 编译单元:一个.cc或.cpp文件作为一个编译单元,生成 ...
- 为什么C++模板函数的声明与实现都放在.h文件中
引用C++primer的话:C++支持两种模板编译模式包含模式(Inclusion Model )和分离模式(Separation Model) 1. 包含编译模式 在包含编译模式下,在每个模板被 ...
- Objective-C 2.0 with Cocoa Foundation --- 3,类的声明和定义
3,类的声明和定义 本系列讲座有着很强的前后相关性,如果你是第一次阅读本篇文章,为了更好的理解本章内容,笔者建议你最好从本系列讲座的第1章开始阅读,请点击这里 . 上一章 我 们写了一个非常简单的Ob ...
- mfcs100ud.lib(dllmodul.obj):error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义
mfcs100ud.lib(dllmodul.obj):error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义 简单地说,就是产生错误的 ...
- 习题 8.5 将本章的例8.4改写为一个多文件的程序:1.将类定义放在头文件arraymax.h中;2.将成员函数定义放在源文件arraymax.cpp中;3.主函数放在源文件file1.cpp中。
C++程序设计(第三版) 谭浩强 习题8.5 个人设计 习题 8.5 将本章的例8.4改写为一个多文件的程序: 1.将类定义放在头文件arraymax.h中: 2.将成员函数定义放在源文件arraym ...
- Python——类的声明与定义
类的声明与定义 Python 是一门面向对象的语言.面向对象编程 - Object Oriented Programming(简称 OOP)是一种编程思想,在面向对象编程中,把对象作为程序的基本单元, ...
- 为什么模板函数的声明和实现都放在.h文件中
当你不使用这个模板函数或模板类,编译器并不实例化它,当你使用时,编译器需要实例化它,因为编译器是一次只能处理一个编译单元,也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义.所以都放在 ...
最新文章
- 负数运算_小学生必备科学常识100问-34数学史(7):负数的产生
- Android输入法遮挡了输入框,使用android:fitsSystemWindows=“true“后界面顶部出现白条解决方案
- linux shell 实现自增版本号
- beego 注解路由无效问题分析
- 【数字信号处理】相关函数 ( 能量信号 | 能量信号的互相关函数 | 能量信号的自相关函数 )
- Commons Logging 快速入门(五)
- 树莓派应用实例5:测量土壤湿度
- Quartz-异常处理
- 关于库存 库存BAPI
- 7月清北学堂培训 Day 5
- 服务器任务管理器详细信息,任务管理器服务器主机
- centos6安装mysql并远程连接_阿里云服务器上安装redis并实现远程连接
- 用户名 不在 sudoers文件中,此事将被报告。
- 做游戏,学编程(C语言) 10 僵尸危机
- 微信小程序 audio 音频 组件
- speedoffice表格如何快速复制整张工作表
- 四、LockSupport与线程中断
- ac9260网卡linux,160Mhz频宽的怒吼,Intel Wireless-AC 9260 无线网卡评测
- 学微积,用手机,人人“知识共享”学真知
- 修正 Newton 公式