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_INCLUDE

class 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;
	else
		s = 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_INCLUDE

class 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;
	else
		s = 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_INCLUDE

class 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;
	else
		s = 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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个链接错误,表示函数 "main" 已经在文件 "1hello world.obj" 定义过了。在 C++ 程序,每个程序都必须有一个名为 "main" 的函数,它是程序的入口点。如果在同一个程序多次定义了 "main" 函数,就会产生这个错误。 解决办法是: - 检查程序是否有多个文件定义了 "main" 函数,如果有,请将其一个删除。 - 检查程序是否有多次定义了 "main" 函数,如果有,请将多余的定义删除。 - 如果您是使用第三方库或组件时遇到这个错误,请检查是否存在重复的定义,并请联系库或组件的提供商寻求帮助。 ### 回答2: 这个错误是由于在同一个程序定义了多个名为"main"的函数导致的。 在C++,每个程序只能有一个入口函数"main"。当在同一个项目有多个源文件时,如果每个源文件定义一个名为"main"的函数,编译器就会报告LNK2005错误。 解决这个错误的方法是确保每个项目只有一个名为"main"的函数。可以检查项目是否存在多余的源文件文件是否定义了多个"main"函数。如果有,可以删除多余的源文件或将额外的"main"函数重命名为其他名称。 另外,有时候这个错误可能是由于错误的链接选项导致的。可以检查项目配置的链接选项,确保没有重复的源文件被包含在链接过程。 总之,要解决LNK2005错误,需要确保每个项目只有一个名为"main"的函数,并且检查配置选项以确保正确的链接。 ### 回答3: 这个错误是由于在程序存在重复定义了main函数所导致的。 在一个C/C++程序,每个源文件只能有一个main函数,作为程序的入口点。当在多个源文件同时定义了main函数时,编译器在链接时就会报错,提示main函数已经在某个obj文件定义过了。 解决这个错误的方法有两种: 1. 删除重复的main函数定义:查找并删除多余的main函数定义,只保留一个即可。通常情况下,只需要在程序的一个文件定义main函数即可。 2. 将重复定义的main函数改为其他名称:如果确实需要在多个源文件定义一个入口函数,可以将其一个main函数改名为其他不重复的函数名,然后修改调用该函数的地方。 总之,在解决这个错误时,需要确保整个程序只有一个main函数的定义,避免在多个源文件重复定义
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值