none
一个C++代码,关于函数的形参 RRS feed

  • 问题

  • 第一次发帖,也是初学程序设计的大一生,水平低处让大家见笑了,希望能不吝指点,谢谢。
    要求声明一个Employee类,其中包括数据成员:姓名,地址,城市,邮编。函数成员Change_name改变姓名,display输出4个数据成员。
    我第一次做的代码如下
    头文件:
    #include <iostream>
    #include <string>
    using namespace std;
    class Employee
    {
    private:
     string name;
     string adress;
     string city;
     string mailnum;
    public:
     Employee(string& n,string& a,string& c,string& m);
     ~Employee();
    void Employee::display ()
     void change_name(string n);

    };
    Employee::Employee(string n,string a,string c,string m)
    {
     name=n;
     adress=a;
     city=c;
     mailnum=m;
    }

    void Employee::change_name(string n)
    {
     name=n;
    }
    void Employee::display ()
    {
     cout << name << "  " << adress << "  ";
     cout << city  << "  "<< mailnum<< endl;
    }
    CPP文件:
    #include "employee.h"
    int main()
    {
     Employee e1("张三","平安大街3号", "北京", "100000");
     e1.display();
     cout << endl;
     e1.change_name("李四");
     e1.display();
     cout << endl;
    }
    构造函数与change_name均错误。
    第二次,其他不变,构造函数和change_name形参改用指针
    Employee::Employee(char *n,char *a,char *c,char *m)
    {
     name=n;
     adress=a;
     city=c;
     mailnum=m;
    }

    void Employee::change_name(char *n)
    {
     name=n;
    }
    成功。
    但是一直没搞清楚原理。
    1)本类的几个数据成员,均是string类的对象,那么我使用string类对象作为形参,应该是正确的?
    到底是错在哪里?请高手指教,谢谢。
    2)另外,我有一个想法,是否可以实现以下语法:
    display(char *S1)
    {cout<<s1}
    然后在调用该函数时,使用某个数据成员作为实参,如:
    e1.display(name);
    以实现以一个函数选择性地输出某个数据成员?
    PS:由于近期期末复习,时间紧张,可能无法第一时间对您的回答做出回应,请谅解

    2009年6月9日 14:45

答案

  • Employee::Employee(string n,string a,string c,string m)这个倒是没错,就是太慢了,这样所有的string都是临时变量,编译器会先生成一个临时变量再复制过去.应该这样写Employee::Employee(string& n,string& a,string& c,string& m)

    第二个没看懂
    baadfood?cafebabe?
    2009年6月9日 15:11
    版主
  • 你的源代码中,构造函数确实有错误,但是change_name函数没有错误。你可以再编译一次看看。

    构造函数的错误在于引用型形参不能接受字符串常量实参。正如我们不能把一个常数赋给引用型变量一样。如int &b=3;//这是错的。3是常数。

      int a=3; int &b=a;//这是对的。右值必须是一个有地址的变量。
    你的构造函数的形参应该改为string,而不是string&。用string会导致值传递,效率上有一定影响。
    如果你一定要用string&,那么构造函数的实参就不能用字符串,而应该用字符串变量。
    string a1="张三";
     string b1="平安大街3号";
     string c1="北京";
      string d1="100000";
      a1="李四";
     Employee e1(a1,b1,c1,d1);//用字符串变量。

    另外,你的析构函数后面应该加上{}

      

    2009年6月9日 16:21
  • 楼主你好,

    对于传入参数在C++03中尽量使用const &类型,但是对于POD类型加不加引用是没有区别的。test(const int& n) 和test(const int)没有区别。
    这里const 保证传入参数引用的对象不会被改变。
    在即将发布的C++0X中可以使用右值引用代替const &
    类似
    test(yourClass && rhs);
    关于第二个问题从语言上当然是可以的。但前提是std::string有隐式转换成char*的操作符。否则这里会类型不匹配。
    不过你这里Display是一个共有函数,但是成员变量是私有的,在类外使用Display(char*)的时候无法传入Employee的成员变量作为参数。
    你可以为Employee的成员变量做对应的Get方法。


    麻烦把正确答案设为解答。
    2009年6月10日 0:39
    版主

全部回复

  • Employee::Employee(string n,string a,string c,string m)这个倒是没错,就是太慢了,这样所有的string都是临时变量,编译器会先生成一个临时变量再复制过去.应该这样写Employee::Employee(string& n,string& a,string& c,string& m)

    第二个没看懂
    baadfood?cafebabe?
    2009年6月9日 15:11
    版主
  • 谢谢回答。那是否应该在尽量在被调函数中使用引用而不是变量来提高效率?比如一个简单的 1)test(int& n){略} 比test(int n){略} 更有效率?
    2)编辑掉
    2009年6月9日 16:12
  • 你的源代码中,构造函数确实有错误,但是change_name函数没有错误。你可以再编译一次看看。

    构造函数的错误在于引用型形参不能接受字符串常量实参。正如我们不能把一个常数赋给引用型变量一样。如int &b=3;//这是错的。3是常数。

      int a=3; int &b=a;//这是对的。右值必须是一个有地址的变量。
    你的构造函数的形参应该改为string,而不是string&。用string会导致值传递,效率上有一定影响。
    如果你一定要用string&,那么构造函数的实参就不能用字符串,而应该用字符串变量。
    string a1="张三";
     string b1="平安大街3号";
     string c1="北京";
      string d1="100000";
      a1="李四";
     Employee e1(a1,b1,c1,d1);//用字符串变量。

    另外,你的析构函数后面应该加上{}

      

    2009年6月9日 16:21
  • 楼主你好,

    对于传入参数在C++03中尽量使用const &类型,但是对于POD类型加不加引用是没有区别的。test(const int& n) 和test(const int)没有区别。
    这里const 保证传入参数引用的对象不会被改变。
    在即将发布的C++0X中可以使用右值引用代替const &
    类似
    test(yourClass && rhs);
    关于第二个问题从语言上当然是可以的。但前提是std::string有隐式转换成char*的操作符。否则这里会类型不匹配。
    不过你这里Display是一个共有函数,但是成员变量是私有的,在类外使用Display(char*)的时候无法传入Employee的成员变量作为参数。
    你可以为Employee的成员变量做对应的Get方法。


    麻烦把正确答案设为解答。
    2009年6月10日 0:39
    版主
  • test(int& n){略} 比test(int n){略} 这个效率一样,但是一般int这些并非类或者结构型变量是不用引用传址的,除非你要修改传过来的n在原函数中的值.因为引用传址传的是一个指针,系统中是一个push一个pop两个指令,int也是两这个指令,效率相同.

    但是结构或者类若不是引用传址,系统会先在栈里分配一个临时变量出来,然后在进行调用类的构造函数,再把成员变量进行赋值,等该函数返回后还要进行调用析构函数,这样就会使本来很简单的工作出现很多无用功,导致程序效率下降.
    baadfood?cafebabe?
    2009年6月10日 4:55
    版主
  • 谢谢大家的答复,我看了之后又去试了几次,基本上了解了。
    看来还是使用指针比较好...
    再次感谢。

    顺便问一下,这论坛有精华区没?
    2009年6月10日 10:39
  • #ifndef EMPLOYEE
    #define EMPLOYEE

    #include <string>
    #include <iostream>


    class Employee
    {
    public:
     Employee(const std::string& n,const std::string& a,const std::string& c,const std::string& m)
      :name(n),address(a),city(c),mailnum(m){}
     ~Employee(){}
     void Display();
     void change_name(const std::string& n);  

    private:
     std::string name;
     std::string address;
     std::string city;
     std::string mailnum;
    };

    inline void Employee::Display()
    {
     std::cout<<name<<" "<<address<<" "
      <<city<<" "<<mailnum;
    }

    inline void Employee::change_name(const std::string &n)
    {
     name=n;
    }

     

    #endif

    2009年6月11日 3:44