简体   繁体   English

C++ 代码 - 在同一 class 的构造函数中调用一个 class 的构造函数

[英]C++ code -calling a constructor of one class within a constructor of same class

I am trying to compile this C++ code unfortunately, I failed to compile the code below.不幸的是,我正在尝试编译这个 C++ 代码,我未能编译下面的代码。 Can you help me by explaining why I am getting this error?你能帮我解释为什么我收到这个错误吗?

#include <iostream>
#include <cstring>
using namespace std;

class student
{
   private:
    char name[10];
    int id;
    int fee;
       public:
           student(char name[10],int id)
           {
               strcpy(this->name,name);  //string copy
               this->id=id;
               fee=0;
           }
           student(char name[10],int id,int fee)
           {
               student::student(name,id); //calling a constructor of one class 
                                         // within a constructor of same class
               this->fee=fee;
           }
           void show() //print function
           {
               cout<<"Name:"<<name<<endl;
               cout<<"id:"<<id<<endl;
               cout<<"fee:"<<fee<<endl<<endl;
           }
};

int main()
{
 student s1("DAVID",123);
 student s2("WILLIAM",124,5000);
 s1.show();
 s2.show();

    return 0;
}

Below is the error GCC is complaining about.: main.cpp|20|error: cannot call constructor 'student::student' directly [-fpermissive]|下面是 GCC 抱怨的错误: main.cpp|20|error: cannot call constructor 'student::student' directly [-fpermissive]|

As rightly suggested by @sweenish, You must do the constructor delegation in the initialization section.正如@sweenish 正确建议的那样,您必须在初始化部分执行构造函数委托。 Something like this:像这样的东西:

#include <iostream>
#include <cstring>
using namespace std;

class student
{
   private:
    char name[10];
    int id;
    int fee;
       public:
           student(char name[10],int id)
           {
               strcpy(this->name,name);  //string copy
               this->id=id;
               fee=0;
           }
           student(char name[10],int id,int fee): student(name, id) // constructor delegation
           {
               this->fee=fee;
           }
           void show() //print function
           {
               cout<<"Name:"<<name<<endl;
               cout<<"id:"<<id<<endl;
               cout<<"fee:"<<fee<<endl<<endl;
           }
};

int main()
{
 student s1("DAVID",123);
 student s2("WILLIAM",124,5000);
 s1.show();
 s2.show();

    return 0;
}

Also, an advice for you.另外,给你一个建议。 You may define the more specialized constructor and delegate the responsibility of less specialized constructors to more specialized ones.您可以定义更专业的构造函数,并将不那么专业的构造函数的责任委托给更专业的构造函数。

#include <iostream>
#include <cstring>
using namespace std;

class student
{
   private:
    char name[10];
    int id;
    int fee;
       public:
           student(char name[10],int id, int fee): id{id}, fee{fee} // more specialized
           {
               strcpy(this->name,name);  //string copy
           }
           student(char name[10],int id): student(name, id, 0) { } // less specialized calling the more specialized constructor
           void show() //print function
           {
               cout<<"Name:"<<name<<endl;
               cout<<"id:"<<id<<endl;
               cout<<"fee:"<<fee<<endl<<endl;
           }
};

int main()
{
 student s1("DAVID",123);
 student s2("WILLIAM",124,5000);
 s1.show();
 s2.show();

    return 0;
}

Here's your code with changes made to get it compiling;这是您的代码,其中进行了更改以使其编译; I marked the changes with comments.我用评论标记了更改。

#include <iostream>
// #include <cstring>  // CHANGED: Prefer C++ ways when writing C++
#include <string>  // CHANGED: The C++ way
// using namespace std;  // CHANGED: Bad practice

class student {
 private:
  std::string name{};  // CHANGED: Move from C-string to std::string
  int id = 0;          // CHANGED: Default member initialization
  int fee = 0;

 public:
  // CHANGED: Move from C-string to std::string
  student(std::string name, int id)
      : name(name),
        id(id)
  // CHANGED: ^^ Utilize initialization section
  {
    // CHANGED: Not needed anymore
    //  strcpy(this->name,name);  //string copy
    //  this->id=id;
    //  fee=0;
  }

  student(std::string name, int id, int fee) : student(name, id) {
    // CHANGED: Not needed anymore
    //  student::student(name,id); //calling a constructor of one class
    //                            // within a constructor of same class
    // NOTE: Inconsistency with other ctor w.r.t. this->
    this->fee = fee;
  }

  void show()  // print function
  {
    std::cout << "Name:" << name << '\n';
    std::cout << "id:" << id << '\n';
    std::cout << "fee:" << fee << "\n\n";
  }
};

int main() {
  student s1("DAVID", 123);
  student s2("WILLIAM", 124, 5000);
  s1.show();
  s2.show();

  return 0;
}

Here is the same code, but with the stuff I commented out removed to make it easier to read.这是相同的代码,但删除了我注释掉的内容以使其更易于阅读。

#include <iostream>
#include <string>

class student {
 private:
  std::string name{};
  int id = 0;
  int fee = 0;

 public:
  student(std::string name, int id) : name(name), id(id) {}

  student(std::string name, int id, int fee) : student(name, id) {
    this->fee = fee;
  }

  void show()
  {
    std::cout << "Name:" << name << '\n';
    std::cout << "id:" << id << '\n';
    std::cout << "fee:" << fee << "\n\n";
  }
};

int main() {
  student s1("DAVID", 123);
  student s2("WILLIAM", 124, 5000);
  s1.show();
  s2.show();

  return 0;
}

The initialization section follows the parameter list and is marked with : .初始化部分在参数列表之后并用:标记。 You then initialize each member, in the order they are declared .然后按照声明的顺序初始化每个成员。

In the case of the constructor doing the delegating, you are unable to initialize fee in the initialization section.在构造函数进行委托的情况下,您无法在初始化部分初始化fee The error I receive is a delegating constructor cannot have other mem-initializers .我收到的错误是a delegating constructor cannot have other mem-initializers

I don't like splitting my initialization like that, and if you insist on delegating constructor calls for this class, implement the most specific constructor and delegate to it with your less specific constructors.我不喜欢这样拆分我的初始化,如果你坚持委托构造函数调用这个 class,实现最具体的构造函数并用你不太具体的构造函数委托给它。 I prefer default member initialization as I think it leads to less confusion and written code overall.我更喜欢默认成员初始化,因为我认为它会减少混乱和整体编写代码。

The code then compiles and you get the expected output:然后代码编译,你会得到预期的 output:

Name:DAVID
id:123
fee:0

Name:WILLIAM
id:124
fee:5000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM