1

我试图在另一个类的构造函数中分配一个类的成员。但我收到“无法分配,因为成员是私人的”的错误。代码是这样的:

Class Class1 {
    private:
        string name;
        string city;
}

Class Class2 {
    private: 
        string id;
        string age;

            Class1 var; //Class1 type variable defined.

    Public:    
        Class2(){   // Now I will define constructor.

        }
        Class2(Class1&, string name1, string city1) {
            var.name = name1;     // error reported , class1 private member
            var.city = city1;     // error reported , class1 private member
        }
}
4

6 回答 6

1

首先,让我们解决一些简单的问题。你Class Class1 { ... }用来定义一个类,当它应该是class Class1 { ... };. 也就是说,关键字 isclass并且您需要以分号结束定义。此外,您的Class2构造函数的第一个参数是类型Class1&,但您甚至没有使用它。Class1您在这里传递的任何内容都将被浪费。

在您的示例中,是var类型并且Class1是. 这并没有赋予任何特殊的特权来访问s 私人成员。他们是完全私人的。Class2Class2Class1

在您的标题中,您说您正在覆盖构造函数。覆盖仅适用于类继承。从另一个类继承的类可能会覆盖其成员函数。所以现在,不清楚你是想Class1成为基类还是Class2.

如果继承是您正在寻找的,您应该更改您的声明Class2to class Class2 : public Class1 { ... };。这意味着Class2继承自Class1. 您仍然无法访问其中的成员Class1,因为它们是私有的。要使它们可用于您的派生类,您需要使它们成为protectedpublic- 前者是首选。

class Class1 {
  protected:
    Class1(string name, string city) : name(name), city(city) { }
    string name;
    string city;
};

class Class2 : public Class1 {
  private: 
    string id;
    string age;

  public:
    Class2(string name1, string city1)
      : Class1(name1, city1)
    { }
};

如果您想要组合 - 也就是说,Class1是的成员Class2- 那么您需要提供Class2一些方法来设置Class1. 目前,它的成员是私人的,所以你不能做任何事情。你可以制作它们public,但那将是非常不鼓励的。一种更好的方法是提供允许这样做的公共setNamesetCity功能:Class1Class2

var.setName(name1);
var.setCity(city1);

更好的是,因为我倾向于认为为了它而制作 setter 是非常糟糕的设计,所以您应该提供Class一个构造函数来设置名称和城市并varClass1的初始化列表中进行初始化:

class Class1 {
  public:
    Class1(const string& name, const string& city)
      : name(name), city(city)
    { }
  private:
    string name;
    string city;
};

class Class2 {
  private: 
    string id;
    string age;
    Class1 var;

  public:
    Class2(string name1, string city1)
      : var(name1, city1)
    { }
};
于 2012-11-23T20:21:49.327 回答
1

您不能从 class2 为 class1 的私有成员赋值。

我将在类 1 中创建一个构造函数,用于初始化变量名称和城市:

Class1(string n, string c)
{
 name=n;
 city=c;
}

然后在 class2 构造函数中,我将调用该构造函数,如下所示:

Class2(Class1&, string name1, string city1) 
{
   var = Class1(name1,city1);        
}

根据您的代码片段,这是我可以建议的最好的。

于 2012-11-23T20:59:41.280 回答
1

正如在另一个答案中所说,您可以使用构造函数来初始化类 1 的变量:

现在要获取值,您应该在类 1 中执行以下操作:

public string getName()
{
 return name;
}

public string getCity()
{
 return city;
}

将这两个函数添加到您的 class1: 然后在 class2 中,您可以通过调用它们来获取 city 的值:

var.getCity();

或者

var.getName();

这些将使您能够访问 class2 中的 class1 变量。

于 2012-11-23T21:40:14.827 回答
0

正如您的编译器告诉您的那样,name 和 city 对 Class1 1 是私有的,因此只能从 Class 2 中访问。

使用 name 和 city 的唯一方法是向 Class1 添加一个以 name 和 city 作为参数的 Ctor,然后提供(公共)方法(getter/setter)来获取这些值并设置这些值。

于 2012-11-23T20:05:11.120 回答
0

您不能在该类之外设置私有成员变量。

尝试 protected(如果您使用继承)、public(简单的方法)或(最好的!)创建 setter 和 getter 函数,并将这些函数公开。

简单地说(实际上过于简化),您希望所有变量都是私有的,而某些函数是公共的。如果每个变量是私有的并且您想在类外调用它,则每个变量都需要一个 setter 和 getter 函数。

http://www.cplusplus.com/forum/beginner/70937/

于 2012-11-23T20:05:18.157 回答
0

正如其他人所说,您不能从另一个(非朋友)类型访问一个类型的私有成员。曾经。

此外,您正在两阶段初始化您的var成员,这似乎完全没有必要。写一个合适的构造函数

Class1::Class1(std::string const& name, std::string const& city)
: name(name), city(city) {
}

并从以下位置调用它Class2

// what is that first parameter for?
Class2(Class1&, string name, string city)
: var(name,city) {
}

您可以将Class1的构造函数设为公开,也可以将其设为私有并显式地成为好友Class2

于 2012-11-23T20:13:42.943 回答