簡體   English   中英

C++中的運算符重載編譯錯誤

[英]Operator overloading compile error in C++

我正在嘗試制作一個程序來模擬在 C++ 中玩戰艦

#include <iostream>
#include <vector>

class Ship {
public:
    Ship();
    Ship operator<<(const Ship&);
private:
    int x = 0;
    int y = 0;
    std::vector<std::pair<int, int>> ship_loc;      //Ship location
};

Ship::Ship() {
    srand(time(NULL));
    std::vector<std::pair<int, int>> ship_loc;      //Ship location
    for (int i = 0; i < 4; ++i) {
            x = rand() % 20;
            y = rand() % 20;
            std::pair<int, int> coordinates = std::make_pair(x, y);
            ship_loc.push_back(coordinates);
            //ship_loc.push_back(std::pair<x, y>)
    };
};

Ship operator<<(const Ship &s) {
    std::cout << ship_loc[0] << ship_loc[1] << ship_loc[2] << ship_loc[3]
            << std::endl;
}

int main()
{
    Ship first_ship;
    std::cout << first_ship;
}

每當我嘗試編譯它時,它都會給我:

battleship.cpp:26:30: error: âShip operator<<(const Ship&)â must take exactly two           arguments
battleship.cpp: In function âint main()â:
battleship.cpp:34:25: error: cannot bind âstd::ostream {aka std::basic_ostream<char>}â     lvalue to âstd::basic_ostream<char>&&â
In file included from /usr/include/c++/4.7/iostream:40:0,
             from battleship.cpp:1:
/usr/include/c++/4.7/ostream:600:5: error:   initializing argument 1 of     âstd::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&,     const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Ship]â

顯然對課程還不是很有經驗。 在所有。

以下行不符合您的意圖:

  Ship operator<<(const Ship&);

當您重載<<運算符時,您不能返回Ship並且第一個參數必須是ostream類型。 它的返回類型必須是std::ostream&引用來自該線程的答案之一: C++ Operator Overloading

流操作符是最常見的重載操作符之一,是二元中綴操作符,其語法對它們是成員還是非成員沒有限制。 因為它們改變了它們的左參數(它們改變了流的狀態),所以根據經驗法則,它們應該被實現為它們的左操作數類型的成員。 然而,它們的左操作數是來自標准庫的流,雖然標准庫定義的大多數流輸出和輸入操作符確實被定義為流類的成員,當你為自己的類型實現輸出和輸入操作時,你無法更改標准庫的流類型。 這就是為什么您需要為您自己的類型將這些運算符實現為非成員函數的原因。

一種方法是使用規范形式實現它:

std::ostream& operator<<(std::ostream& os, const Ship& obj)
{
    // write obj information
    return os;
 }

您將operator <<聲明為成員函數

Ship operator<<(const Ship&);

這意味着左操作數是類 Ship 的一個實例。 所以它可以被稱為

Ship a, b;

a << b;

但很明顯你不想要這個。

如果要在輸出流中輸出 Ship 類的對象,則運算符必須是非成員函數。 您可以將其定義為類的友元函數。 例如

class Ship {
public:
    Ship();
    friend std::ostream & operator <<( std::ostream &os, const Ship& );
private:
    int x = 0;
    int y = 0;
    std::vector<std::pair<int, int>> ship_loc;      //Ship location
};

然后你可以將它定義為例如以下方式

std::ostream & operator <<( std::ostream &os, const Ship &s) 
{
    os << "( " << s.ship_loc[0].first << ", " << s.ship_loc[0].second << " )" 
       << ", ( " << s.ship_loc[1].first << ", " << s.ship_loc[1].second << " )"
       << ", ( " << <.ship_loc[2].first << ", " << s.ship_loc[3].second << " ) "
       << ", ( " << <.ship_loc[3].first << ", " << s.ship_loc[3].second << " ) "
       << std::endl;

   return os;
}

此外,由於坐標數是固定的,因此無需使用std::vector 改用std::array<std::pair<int, int>, 4>

也刪除語句

std::vector<std::pair<int, int>> ship_loc;      //Ship location

從構造函數。 它是一個局部變量。 您需要填充數據成員 ship_loc 而不是這個局部變量。

您錯誤地重載了operator<< ,您想要的簽名類似於:

std::ostream& operator<<(std::ostream& os, const Ship& s);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM