【问题标题】:C++ << overloading with ostream for correct formattingC++ << 使用 ostream 重载以获得正确的格式
【发布时间】:2012-11-23 17:54:52
【问题描述】:

我已经开始编写自己的链接列表,它可以很好地打印数字,但我使用模板来确定类型名称以用于对象。因此,除了打印对象外,我输入数据没有问题。这些类出现以下错误,但 Visual Studio 2010 没有给出行号。我要做的就是允许从链接列表中以正确的格式输出不同类型的对象。

error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > &
__cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,
class Customer &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVCustomer@@@Z)
already defined in Customer.obj

桂类

//Templates
#include "LinkList.h"
#include "Node.h"

//Classes
#include "Gui.h"
#include "Customer.h"

//Libaries
#include <iostream>

//Namespaces
using namespace std;

int main(){
    Customer c1("TempFirst", "TempLast");
    LinkList<Customer> customerList;
    customerList.insert(c1);

    //Print Linklist
    customerList.print();
    system("pause");
    return 0;
}

客户类别

//Def
#pragma once

//Included Libaries
#include <string>
#include <iostream>
class Customer
{
private:
    std::string firstName;
    std::string lastName;
public:
    Customer();
    Customer(std::string sFirstName, std::string sLastName);
    ~Customer(void);

    //Get Methods
    std::string getFirstName();
    std::string getLastName();

    //Set Methods
    void setFirstName(std::string sFirstname);
    void setLastName(std::string sLastname);

    //Print
};

std::ostream& operator << (std::ostream& output, Customer& customer)
{
    output << "First Name: " << customer.getFirstName() << " "
        << "Last Name: " << customer.getLastName() << std::endl;
    return output;
}

【问题讨论】:

  • 你模板化了

标签: c++ overloading ostream


【解决方案1】:

小心将函数定义放在头文件中。您要么需要内联定义,要么最好将其放入.cpp 文件中。在Customer.h 中放一个函数原型即可:

// Customer.h
std::ostream& operator << (std::ostream& output, Customer& customer);

并将完整的定义放在Customer.cpp

// Customer.cpp
std::ostream& operator << (std::ostream& output, Customer& customer)
{
    output << "First Name: " << customer.getFirstName() << " "
           << "Last Name: "  << customer.getLastName()  << std::endl;
    return output;
}

或者,如果你真的想要头文件中的定义,那么添加inline 关键字。内联定义必须放在头文件中,从本质上讲,它们没有外部链接,也不会触发重复定义错误。

inline std::ostream& operator << (std::ostream& output, Customer& customer)
{
    ...
}

【讨论】:

  • 很好,我没有意识到我是从 Java 背景来做的,我知道我是如何犯这个错误的。谢谢,你解决了我的问题。
【解决方案2】:

您没有得到行号,因为直到错误才被检测到 链接时间,链接器看不到任何源代码。问题是 您已将函数定义放在标题中;这只是 如果函数是函数模板或已声明,则合法 inline。通常的程序是在 头文件,并将定义放在与类相同的源文件中 成员函数定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    相关资源
    最近更新 更多