C ++奇怪编译错误:错误:从类“对象”更改“对象”的含义

时间:2008-11-12 02:13:51

标签: c++ xcode

我甚至不知道该去哪里。谷歌不是很有帮助。和我之前的问题一样。我正在使用TextMate的Command + R来编译项目。

  

game.h:16:错误:'Player * HalfSet :: Player()const'的声明

     

players.h:11:错误:从'class Player'改变'Player'的含义

     

game.h:21:错误:'播放器'不是类型

player.h文件(部分)

#ifndef PLAYERS_H
#define PLAYERS_H
using namespace std;

#include <string>
#include <vector>
#include <istream>
#include <iomanip>
#include "generics.h"

class Player{ //Line 11
public:
    //getters
    long Id() const;
    string FirstName() const;
    string LastName() const;
    string Country() const;
    //setters
    void setId(long id);
    void setFirstName(string s);
    void setLastName(string s);
    void setCountry(string s);
    //serializing functions
    void display(ostream &out);
    void read(istream &in);
    void write(ostream &out);
    //Initalizers
    Player();
    Player(istream &in);
    Player(string firstName, string lastName);
    Player(string firstName, string lastName, string country);
    Player(long id, string firstName, string lastName, string country);
    ~Player();
private:
    long _id;
    string _firstName;
    string _lastName;
    string _country;
};

game.h文件(部分)

#ifndef GAME_H
#define GAME_H

#include "generics.h"
#include "players.h"
#include <string>
#include <vector>
#include <istream>
#include <iomanip>

using namespace std;

class HalfSet{
public:
    //getters
    Player* Player() const; //Line 16
    int GamesWon() const;
    int TotalPoints() const;
    int Errors() const;
    //setters
    void setPlayer(Player* p);
    void setGamesWon(int games);
    void setTotalPoints(int points);
    void setErrors(int errors);
    //Serialization
    void display(ostream &out) const;
    void read(istream &in) const;
    void write(ostream &out) const;
    //Initalizers
    HalfSet();
    ~HalfSet();
private:
    Player* _player;
    int _gamesWon;
    int _points;
    int _errors;
};

这里发生了什么?

3 个答案:

答案 0 :(得分:16)

在C ++中,您不能将函数命名为类/ struct / typedef。你有一个名为“Player”的类,所以HalfSet类有一个名为“Player”(“Player * Player()”)的函数。您需要重命名其中一个(可能将HalfSet的Player()更改为getPlayer()或其他一些)。

答案 1 :(得分:8)

您的问题是在范围中查找名称。在HalfSet :: setPlayer(Player *)的声明中,需要查找非限定名称Player。尝试的第一个范围是类HalfSet。在该范围内,Player的查找找到函数HalfSet :: Player,而不是全局类:: Player。

解决方案是使用限定名称:: Player。这告诉编译器哪个范围用于查找(全局),这反过来意味着甚至不考虑HalfSet :: Player。

答案 2 :(得分:5)

目前对这个问题的回答是不正确的,它说:

  

在C ++中,您不能将函数命名为类/ struct / typedef

允许使用函数隐藏类的名称,如果我们转到draft Pre C++11 standard部分3.3.7 名称隐藏,则说:

  

可以通过名称隐藏类名(9.1)或枚举名称(7.2)   在同一范围内声明的对象,函数或枚举器。如果一个   类或枚举名称以及对象,函数或枚举器   在同一范围内(以任何顺序)声明具有相同名称的   类或枚举名称隐藏在对象,函数或的任何位置   枚举器名称可见。

因此,您拥有该函数和名为Player的类的事实不是问题,实际上以下代码是有效的:

class Player
{
} ;

Player* Player() ;

我们可以使用elaborated type specifier取消隐藏类类型。

据我所知,这违反了3.3.6 类范围2,其中包含:

  

类S中使用的名称N应引用其中的相同声明   上下文,并在完成范围内重新评估   违反此规则需要诊断。

所以在这种情况下Player改变了从函数的含义,我不清楚它是如此严格,但我可以看到它可以这样读。这似乎是gcc在检测到此违规行为时使用的消息,我们可以从similar question看到。

使用精心设计的类型说明符可防止改变含义:

class Player* Player() const ;