【问题标题】:Constructor cannot access private members of its own class构造函数不能访问自己类的私有成员
【发布时间】:2009-06-07 19:17:19
【问题描述】:

我在 Visual Studio 2008 中收到以下错误:错误 C2248:“Town::Town”:无法访问在“Town”类中声明的私有成员。看起来构造函数无法访问其自己的类的成员。知道发生了什么吗? 代码如下:

我有这个:

template<class T> class Tree{...}

还有这个类:

class Town{
    Town(int number):number(number){};
    ...
private: 
    int number;
};

在这个类中使用的:

class Country{
public:
    StatusType AddTown(Shore side, int location, int maxNeighborhoods);
private:
    Tree<Town> towns[2];
    ...
}

这里是 AddTown 函数:

StatusType Country::AddTown(Shore side, int location, int maxNeighborhoods){
    if (maxNeighborhoods<0 || location<0){
        return INVALID_INPUT;
    }
    Town* dummy= new Town(location);//Here be error C2248
    if (towns[side].find(*dummy)!=NULL){
        delete dummy;
        return FAILURE;
    }
    SouthBorder* dummyBorder;
    (side==NORTH)?dummyBorder=new SouthBorder(location,0):dummyBorder=new SouthBorder(0,location);
    if (southBorders.find(*dummyBorder)!=NULL){
        delete dummyBorder;
        return FAILURE;
    }
    towns[side].add(*dummy);
    delete dummyBorder;
    return SUCCESS;
}

【问题讨论】:

    标签: c++ visual-studio-2008 templates


    【解决方案1】:

    默认情况下,类访问级别是私有的。如果您不添加 public: 在 Town 构造函数之前,它将是私有的。

    class Town{
    public: // <- add this
        Town(int number):number(number){};
        ...
    private: 
        int number;
    };
    

    【讨论】:

      【解决方案2】:

      这段代码有上面列出的两个逻辑问题。非公共声明和通过使用作为内部传递的相同名称来隐藏成员变量。

      考虑到我们以“数字”变量为例。

      过去,例如在 c++ 中,作为私有内部变量的成员变量会以“m_number”作为前缀。或者有些人只会做'_number'。

      只是 'num' 是一个很好的重命名,但可能不清楚它是否只是相同的值。我想这是一个尚未真正解决的内部私有成员变量命名问题。

      Python 使用 'self.number' 与传入的 'number' 区分开来,这是一个不错的解决方案。

      但无论是什么平台,拥有一个私有变量成员命名系统总是好的,它可以帮助您避免在出现名称冲突时被黑客入侵。

      【讨论】:

      • 总体思路+1。但是,虽然很常见,但您不应使用下划线“_”作为前缀,因为标准将这些名称保留给“实现”,其中实现是编译器/STL 实现者。您还可以在 C++ 中使用“this”,就像在 python 中使用“self”一样,将属性与其他标识符(局部变量/参数)区分开来。
      【解决方案3】:

      你为隐藏成员变量的函数声明了一个局部变量:

      城镇(int number):number(number){};

      试试这个

      Town(int num):number(num){};

      【讨论】:

      • 初始化列表对这个效果有点特殊。同名参数在初始化列表中不会隐藏属性。该参数将尽可能隐藏属性的名称。当编译器遇到 ':number(number)' 时,第一个 'number' 必须是要编译的代码的属性。第二个“数字”可以是其中一个,并且参数将属性隐藏在那里(就像构造函数块内的任何地方一样)。但是操作码是正确的。
      猜你喜欢
      • 1970-01-01
      • 2021-03-26
      • 2016-08-01
      • 2017-04-04
      • 1970-01-01
      • 2021-04-17
      • 2023-03-24
      • 1970-01-01
      • 2018-04-19
      相关资源
      最近更新 更多