精华内容
下载资源
问答
  • 类对象作为函数形参
    万次阅读
    2017-02-21 21:02:14

    网上看见一段代码,是关于类对象作为函数的参数,其中有几点知识,贴出来大家一起学习。

    直接来看代码:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class people 
    {
    private:
    	char *name;
    	int age;
    public:
    	people(char *namestr,int i);
    	~people();
    	char *getname();
    	int getage();
    };
    people::people(char *namestr,int i)
    {
    	name=new char[strlen(namestr)+1];
    	strcpy(name,namestr);
    	age=i;
    }
    people::~people()
    {
    	delete name;
    }
    char *people::getname()
    {
    	return name;
    }
    int people::getage()
    {
    	return age;
    }
    void display(people x)
    {
    	cout<<"people\'s name: "<<x.getname()<<endl;
    	cout<<"people\'s age: "<<x.getage()<<endl;
    }
    
    int main()
    {
    	people p("xieyi",30);
    	display(p);
    	return 0;
    }
    1.首先要明确void display(people x){...}是 传值方式传参实参要向形参复制对象,在复制对象时会 调用拷贝构造函数

    2.由于people类中没有显示定义拷贝构造函数,将使用默认拷贝构造函数,那么将不会自动复制堆资源(即通过new得到的资源);

    3.因此,void display(people x){...}执行时,会调用默认拷贝构造函数,所以x对象中的name属性没有赋值,指向了未知的地址,因此x.getname()会出错;


    解决的办法有两个:

    1.使用引用传参

    void display(people& x)
    void display(const people& x);

    2.显示定义拷贝构造函数

    people(const people& x)
    {
    	this->name = x.name;
    	this->age = x.age;
    }




    更多相关内容
  • 类对象作为形参,本质上与基本类型作为形参并无区别。但是考虑到普通类型作为形参,使用的是值传递,也就是将实参值拷贝一份给形参。如果是对象的话,此时将会调用一个拷贝构造函数。也就是以实参为参数拷贝构造...

    任务描述

    编写一个 output 函数,以 Int 的常引用作为形参,其功能是输出形参的成员变量的值。输出为一行。

    相关知识

    类对象作为形参,本质上与基本类型作为形参并无区别。但是考虑到普通类型作为形参,使用的是值传递,也就是将实参值拷贝一份给形参。如果是类对象的话,此时将会调用一个拷贝构造函数。也就是以实参为参数拷贝构造形参。
    如果类对象本身特别复杂,这个拷贝过程显然也会更加耗时,如此便会降低程序运行的效率。

    1. class T{
      public:
      T(){}
      T(const T&rhs){}
      };
      void f(T x){}
      int main(){
      T a;
      f(a);//此处会发生一个拷贝构造,也就是用a去拷贝构造x
      return 0;
      }

    出于效率的考虑,一般对于类类型的形参,一般会使用引用类型。如下:

    1. void f(T& x){}//形参是T&类型,而不是普通的T类型

    另一方面,出于程序健壮性、可读性的考虑,如果f函数并没有改变形参的内容,则还会给形参加上一个 const 修饰。如下:

    1. void f(const T&x){}

    编程要求

    根据提示,在右侧编辑器的Begin-End区域内补充代码。

    测试说明

    本关共3个文件,Int.h、Int.cpp 和 main.cpp。其中 Int.h 和 main.cpp 不得改动,用户只能修改 Int.cpp 中的内容。

    Int.h内容如下:

    1. /**
      * 这是一个包装类(wrapper class),包装类在C++中有点小小的用处(基本上没用),在Java中的用处更大一些。
      */
      
      #ifndef _INT_H_ //这是define guard
      #define _INT_H_ //在C和C++中,头文件都应该有这玩意
      
      class Int{
      
      private://这是访问控制——私有的
      int value; //这是数据成员,我们称Int是基本类型int的包装类,就是因为Int里面只有一个int类型的数据成员
      
      public: //这是公有的
      Int():value(0){}
      Int(Int const&rhs):value(rhs.value){}
      Int(int v):value(v){}
      
      int getValue()const{return value;}
      
      };//记住这里有一个分号
      
      //注意这里有一个函数声明,也就是需要实现的函数
      //一般而言,这个函数声明应该写在另一个头文件中,如IntOp.h
      void output(Int const&);
      
      #endif

    main.cpp 内容如下:

    1. #include "Int.h"
      #include <iostream>
      using namespace std;
      
      int main(){
      int x;
      cin >> x;
      Int a(x);
      output(a);
      return 0;
      }

    要求在Int.cpp文件中完成output()函数,该函数的功能是输出形参的数据成员,并且换一行。

    /********* Begin ********/
    #include"Int.h"
    #include<iostream>
    using namespace std;
    void output(const Int&x)
    {
        cout<<x.getValue()<<endl;
    }
    
    
    /********* End **********/

    展开全文
  • C++中,对象作为函数参数的几种情况

    千次阅读 2020-10-07 09:37:34
    Passing Objects to Functions (对象作为函数参数) Objects as Function Arguments (对象作为函数参数) You can pass objects by value or by reference. (对象作为函数参数,可以按值传递,也可以按引用传递) ...

    Passing Objects to Functions (对象作为函数参数)

    1. Objects as Function Arguments (对象作为函数参数)
    You can pass objects by value or by reference. 
    (对象作为函数参数,可以按值传递,也可以按引用传递)
    

    (1) Objects as Function Return Value(对象作为函数参数)

    // Pass by value
    void print( Circle c ) {  //作为函数参数
      /* … */
    }
    
    int main() {
      Circle myCircle(5.0);
      print( myCircle );  //作为函数参数
      /* … */
    }
    

    其中,先创建一个myCircle对象,然后print函数调用该对象。

    (2) Objects Reference as Function Return Value(对象引用作为函数参数)

    void print( Circle& c ) {
      /* … */
    }
    
    int main() {
      Circle myCircle(5.0);
      print( myCircle );
      /* … */
    }
    

    虽然在调用print函数时传入的参数是对象,但是在print函数定义中,使用了引用类型。

    (3) Objects Pointer as Function Return Value(对象指针作为函数参数)

    // Pass by pointer
    void print( Circle* c ) {
      /* … */
    }
    
    int main() {
      Circle myCircle(5.0);
      print( &myCircle );
      /* … */
    }
    

    在调用print函数时传入的参数是创建的对象的地址,在print函数定义中,对myCircle对象进行了解引用。

    1. Objects as Function Return Value(对象作为函数返回值)
    // class Object { ... };
    Object f ( /*函数形参*/ ){
      // Do something
      return Object(args);
    }
    
    
    // main() {
    Object o = f ( /*实参*/ );
    
    f( /*实参*/ ).memberFunction();
    

    创建了一个函数对象o = f(args),可以调用函数对象的属性值。object类型的函数定义中返回该对象传入的参数。

    1. Objects Pointer as Function Return Value(对象指针作为函数返回值)
    // class Object { ... };
    Object* f ( /*函数形参*/ ){
      Object* o = new Object(args) // 这是“邪恶”的用法,不要这样做
      // Do something
      return o;
    }
    
    // main() {
    Object* o = f ( /*实参*/ );
    f( /*实参*/ )->memberFunction();
    // 记得要delete o
    

    在该例子中,指针对象o在被创建时的生命周期为f(args)内部,调用完就会被擦除。

    下面是允许的用法

    // class Object { ... };
    Object* f ( Object* p, /*其它形参*/ ){
      // Do something
      return p;
    }
    
    // main() {
    Object* o = f ( /*实参*/ );
    // 不应该delete o
    

    操作的是传入的对象指针,因此调用完后仍然能够返回传入的对象指针。

    • 实践:

    尽可能用const修饰函数返回值类型参数,除非你有特别的目的(使用移动语义等)。

    const Object* f(const Object*  p, /* 其它参数 */) { }
    
    1. Objects Reference as Function Return Value(对象引用作为函数返回值)
    // class Object { ... };
    Object& f ( /*函数形参*/ ){
      Object o {args};
      // Do something
      return o;  //这是邪恶的用法
    }
    

    可行的用法1:

    // class Object { ... };
    class X {
      Object o;
      Object f( /*实参*/ ){
        // Do something
        return o;
      }
    }
    

    o的属性会被保留。

    可行的用法2:

    // class Object { ... };
    Object& f ( Object& p, /*其它形参*/ ){
      // Do something
      return p;
    }
    
    // main() {
    auto& o = f ( /*实参*/ );
    f( /*实参*/ ).memberFunction();
    

    和指针类似。

    • 实践:

    const修饰引用类型的函数返回值,除非你有特别目的(比如使用移动语义)

    const Object& f( /* args */) { }
    
    1. 一些高阶问题

    传值,传址,传指针,传引用都是骗初学者的。C++中有意义的概念是传值和传引用。

    Differences between a pointer variable and a reference variable
    Difference between passing by reference vs. passing by value?

    展开全文
  • c++对象作为方法参数(即函数参数)

    万次阅读 多人点赞 2019-09-12 17:13:03
    c++对象作为参数传递时,有三种传递方式 #include <iostream> using namespace std; //求圆的面积 class Mycircle{ public: double r; double s; public: double getR(){ return r; } void setR...

    c++类的对象作为参数传递时,有三种传递方式

    #include <iostream>
    
    using namespace std;
    
    //求圆的面积
    class Mycircle{
    
    public:
        double r;
        double s;
    public:
        double getR(){
            return r;
        }
        void setR(double a){
            r = a;
    
        }
        double getS(){
            s = 3.14*r*r;
            return s;
        }
    
    
    };
    //类做函数参数有三种方法
    /*第一种,最常用(这种适用于普通类型变量传值,当对象作为函数参数时候用引用形式,即第二种,减少内存开销)
    
    void printCircle(Mycircle mc){
        cout<<"半径是"<<mc.getR()<<endl;
    }
    
    */
    
    //第二种,引用方式(与第一种的调用方法一样,直接传参数,这是当传递的参数是一个对象时使用引用方式传递)
    void printCircle(Mycircle &mc){
        cout<<"半径是"<<mc.getR()<<endl;
    }
    //第三种,指针(需要传入一个地址)
    void printCircle(Mycircle *mc){
        cout<<"半径是"<<mc->getR()<<endl;
        /*不能使用mc.getR()或mc.r,与结构体不一样(结构体既可以A.B,也可以A->B,等价的),但对象调用方法是
        A.B,对象指针调用方法是A->B。
        简单来说,“->”的前面一定是一个“指向结构体的指针”或“对象指针”,后面是结构或对象的一个"成员" 。
        如有:A->B,则可以肯定A是一个结构体指针或类的对象指针,而B是A中的一个成员。
        类封装了变量和方法,更丰富
        */
    }
    int main()
    {
        Mycircle c;
        c.setR(2.4);
        cout << "面积是"<<c.getS() << endl;
        printCircle(&c);//指针方式
        printCircle(c);//引用方式
        //printCircle(c);//常用方式,这里注释掉,因为测试会与引用方式重载冲突
        return 0;
    }
    
    展开全文
  • 深入理解指针作为函数形参

    千次阅读 2021-11-27 22:05:22
    接下来,通过一个简单的例子,来演示一下指针作为函数形参的两个容易混淆的问题。 1)可以改变指针指向的内容: void test(int* s) {//指针作为形参 //s = new int(2);//p指向2这块内存空间 *s = 20;//指针指向的...
  • 今天看了有关对象作为函数形参的实现的一些知识,下面谈一谈我的看法。 大家可以想一下基本类型的数据作为函数形参在底层的实现:主调函数将实参压入运行栈中的传参区域,进行形实结合调用被调函数,调用完成后...
  • 【1】C++中对象作为形式参数

    千次阅读 2020-10-31 11:58:26
    那么对象作为形参时是哪种传递呢? 可想而知,对象是引用数据类型,指向了其下的数据成员和方法成员。 我们又知道,值传递相当与将变量的等值复制作为参数传入函数函数内对其修改并不会影响传入值。 相反地,当...
  • 对象作为函数参数

    2012-05-25 09:03:39
    对象作为函数参数  对象本身做参数(传值),传对象副本  对象引用做参数(传地址),传对象本身
  • 第1关:类对象作为函数形参 编写一个output函数,以Int的常引用作为形参,其功能是输出形参的成员变量的值。输出为一行。 /********* Begin ********/ #include "Int.h" #include <iostream> using namespace ...
  • 上面的代码是编译通过的,也就是说,虽然_size是private属性,但在定义拷贝构造函数时,通过this指针获取当前对象的私有变量的同时(基操),居然可以获取到形参对象的私有成员变量,该形参的类型为本类对象的引用...
  • 近来做到几个关于对象作为函数形参,返回值时,构造函数,复制构造函数,析构函数的调用顺序的问题,于是研究了一下,发现问题似乎还有些麻烦,现在在此分享下: 问题一: •对象参数的传递方式 •通过运行栈来...
  • 数组作为函数形参

    千次阅读 2019-05-13 21:50:13
    在翻看以前学习资料时,发现如果用数组作为形参,其大小[即sizeof(形参名)]与指针大小一样——大小为 4。在网上找到一篇写的很好,所以转载过来作为笔记。
  • 在上一篇文章《C函数的“传值调用”和“传址调用”的深入分析》我们分析了函数参数的使用,对于一级指针,理解起来相对容易,而二级指针参数的理解相对难一些,我们先说一下二级指针作为函数形参的目的。 二级指针...
  • 如何将一个类对象作为一个函数的参数呢? 按照以下格式即可: def 函数名(类名) 对,只需要将类名作为形参即可,实测有效。 这一点和C++其实有点像。 我这里是将另外一个文件编写的作为本文件的函数的参数 ...
  • 二维数组作为函数形参

    千次阅读 2018-04-25 15:12:13
    转载:... 在用二维数组名作为参数传递时容易出现Segmention Error。这是因为不能正确为二维数组中元素寻址的问题,正确的方法如下:[cpp] view plaincopy #include <stdlib.
  • 在以后要用的地方,声明一个对象,直接调用其中的成员函数。 但有一个问题是,我们经常需要把我们从数据库里面查询到的东西显示在我们的主窗口的界面上。这时,就是两个之间的数据交换的问题了。 关于这个问题。...
  • c++,对象作为形参时一定会调用复制构造函数吗?答:如果参数是引用传递,则不会调用任何构造函数;如果是按值传递,则调用复制构造函数,按参数的值构造一个临时对象,这个临时对象仅仅在函数执行是存在,函数...
  • c++基础1:指针作为函数形参

    千次阅读 2018-06-07 16:47:03
    指针作为函数形参传入的应用非常广泛,比如:数组名字作为指针传入等等.指针作为形参传入的一大好处就在于可以在函数内部改变指针指向的对象!!!注意,这里的重点是指针指向的对象,而不是改变指针本身.指针和应用作为...
  • 一维数组作为函数形参

    千次阅读 2018-04-25 14:53:53
    在C/C++中,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针。因此尽管函数GetSize的参数data被声明为数组,但它会退化为指针,size3的结果仍然是4. 二、数组的两个特殊性质 (1)不允许拷贝和...
  • C++中对象作为函数形参时的构造函数和析构函数 构造函数和析构函数是C++重要概念。本文将简单讨论当对象作为函数形式参数时,构造函数和析构函数的调用情况。 1. 无拷贝构造函数的情况 这是最简单的情形,中没有...
  • [C++] 将成员函数作为函数形参

    千次阅读 2014-02-21 11:29:09
    函数以及函数对象都可以作为参数来增加其它函数的功能,并且通常作为STL算法的第二个版本的最后一个参数。成员函数是否可以作为形参呢?如果可以,形参表如何写呢?
  • 引用作为函数形参 我定义一个交换函数: void swap(int& x, int& y) { int tmp; tmp = x; x = y; y = tmp; } 在main函数中调用: int x1 = 100; int y1 = 200; TRACE("Before swap x1=%d y1=%d\n",x1...
  • 020:继承自string的MyString 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB // 在此处补充你的代码 描述 程序填空,输出指定结果 #include <...class MyString:public st...
  • js中的对象函数定义以及形参和实参
  • 函数形参的理解

    千次阅读 2020-11-01 18:50:05
    一个典型函数定义包括四个部分:返回类型,函数的名字,形参列表和函数体。格式如下 int max(int a,int b) {函数体} 函数的作用 在我看来,函数的一般作用是对一定的输入产生一定的输出,当然可以没有输入;至于...
  • 作为函数参数(形参结合): 主调函数调用被调函数时,主调函数已经被压入了运行栈中,首先将要传递的参数压入运行栈的一段特殊区域中(这段内存,主调函数和被调函数都可以访问到),再将被调函数压入运行栈中(被...
  • 函数参数有直接变量(如int、char、double等)类型、指针类型和引用类型。 如果参数是变量,传递方式是传值,就是将实参的值复制(复制,意味着空间消耗和时间消耗)到“栈”空间中。 如果参数是指针,传递方式是传址,...
  • 为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象能够返回其地址,而什么样的对象不能够返回其地址?静态变量与局部自动变量的主要区别是什 么? 要想明白这些就需要理解程序...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 107,944
精华内容 43,177
关键字:

类对象作为函数形参