当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《C++奇怪编译错误:错误:从类"对象"更改"对象"的含义》经验,为你挑选了3个好方法。

我甚至不知道该去哪里.谷歌不是很有帮助.和我之前的问题一样.我正在使用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 
#include 
#include 
#include 
#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 
#include 
#include 
#include 

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;
};

这里发生了什么?



1> SoapBox..:

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


不幸的是,Visual C++编译器允许你这样做,所以当你尝试使用g ++编译一些正在使用Windows的东西时,你会感到非常惊讶.
嗯 - 你可以,但不是会员功能.
对第16行执行:: Player*Player()将解决此问题.(按照建议b @MSalters)

2> MSalters..:

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

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



3> Shafik Yaghm..:

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

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

允许使用函数隐藏类的名称,如果我们转到草案Pre C++ 11标准部分3.3.7 名称隐藏它说:

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

所以你有这个函数和一个名为class的Player事实不是问题,实际上下面的代码是有效的:

class Player
{
} ;

Player* Player() ;

我们可以使用精心设计的类型说明符来取消隐藏类类型.

据我所知,这违反了章节3.3.6 范围段落2,其中说:

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

所以在这种情况下Player改变了从函数的含义,我不清楚它是如此严格,但我可以看到它是如何以这种方式读取的.这似乎是在gcc检测到此违规时使用的消息,我们可以从类似的问题中看到.

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

class Player* Player() const ;

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有