精华内容
下载资源
问答
  • 数据成员必须在构造函数初始化列表中初始化: 没有默认构造函数的内嵌对象引用类型的数据成员常数据成员
    数据成员必须在构造函数初始化列表中初始化:
    • 没有默认构造函数的内嵌对象
    • 引用类型的数据成员
    • 常数据成员
    展开全文
  • C++中(const)常数据成员初始化

    千次阅读 2013-11-03 01:42:04
    在类中使用const关键字可以修饰数据成员和成员函数或对象,分别称为数据成员、成员函数和对象。 1常量成员 常量成员包括数据成员、...例子:常数据成员初始化 #include /* run this program using the c

    在类中使用const关键字可以修饰数据成员和成员函数或对象,分别称为数据成员、常成员函数和常对象。

    1常量成员

    常量成员包括常数据成员、静态常数成员和常引用。常数据成员和常引用的初始化只能通过构造函数的成员初始化列表显示进行,而静态常数据成员仍保留静态成员的特征,在类外初始化。

    例子:常数据成员初始化

    #include <iostream>
    
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    using namespace std;
    class Myclass
    {
    	private:
    		int x;							//申明一个成员数据 
    		const int a;				   //申明一个常成员数据 
    		static const int b;			   //申明一个静态的常成员数据 
    		const int &r;				   //声明一个常引用 
    	public:
    		Myclass(int,int);
    		void Print()
    		{
    			cout<<x<<",\t"<<a<<",\t"<<b<<"\t"<<r<<endl;
    		}
    		void Display(const double &r){
    			cout<<r<<endl;
    		}
    };
    
    const int Myclass::b = 15;						//静态数据成员必须在类外初始化 
    Myclass::Myclass(int i,int j):x(i),a(j),r(x){}	//成员列表初始化 
    
    int main(int argc, char** argv) {
    	Myclass m1(10,20),m2(30,40);
    	m1.Print();
    	m2.Print();
    	m2.Display(3.1415926);
    	return 0;
    }


    展开全文
  • 类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化数据... 情况一、需要初始化数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);

    类对象的构造顺序是这样的:
    1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员;
    2.进入构造函数后在构造函数中执行一般赋值与计算。

    使用初始化列表有两个原因:
    原因1.必须这样做:

    《C++ Primer》中提到在以下三种情况下需要使用初始化成员列表:
    情况一、需要初始化的数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);
    情况二、需要初始化const修饰的类成员;
    情况三、需要初始化引用成员数据;

    情况一的说明:数据成员是对象,并且这个对象只有含参数的构造函数,没有无参数的构造函数;

    如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错。

    例如:

    #include "iostream"
    using namespace std;
    
    class Test
    {
     public:
        Test (int, int, int){
        cout <<"Test" << endl;
     };
     private:
        int x;
        int y;
        int z;
    };
    
    class Mytest
    {
     public:
        mytest():test(1,2,3){       //初始化
        cout << "Mytest" << endl;
        };
    private:
        Test test; //声明
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
     Mytest test;
     return 0;
    }

    ①如果没有mytest():test(1,2,3){}初始化列表就会报错:

    1>c:\test\test.cpp(22): error C2512: ‘Test’ : no appropriate default constructor available

    因为Test有了显示的带参数的构造函数,那么他是无法依靠编译器生成无参构造函数的,所以没有三个int型数据,就无法创建Test的对象。Test类对象是MyTest的成员,想要初始化这个对象test,那就只能用成员初始化列表,没有其他办法将参数传递给Test类构造函数。

    ②初始化列表在构造函数执行前执行(这个可以看上面的结果,对同一个变量在初始化列表和构造函数中分别初始化,首先执行参数列表,后在函数体内赋值,后者会覆盖前者)。

    情况二的说明:对象引用或者cosnt修饰的数据成员

    当类成员中含有一个const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化,因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。
    例子:

    class Test
    {
     priate:
        const int a;             //const成员声明
     public:
        Test():a(10){}           //初始化
    };
    
    或
    class Test
    {
     private:
         int &a;                        //声明
     public:
         Test(int a):a(a){}        //初始化
    }

    情况三的说明:子类初始化父类的私有成员,需要在(并且也只能在)参数初始化列表中显示调用父类的构造函数:如下:

    class Test{
    public:
        Test(){};
        Test (int x){ int_x = x;};
        void show(){cout<< int_x << endl;}
    private:
        int int_x;
    };
    
    class Mytest:public Test{
    public:
        Mytest() :Test(110);{
          //Test(110);            //  构造函数只能在初始化列表中被显示调用,不能在构造函数内部被显示调用
        };
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
     Test *p = new Mytest();
     p->show();
     return 0;
    }

    结果:如果在构造函数内部被显示调用输出结果是:1100;
    如果在初始化列表中被显示调用输出结果是:-842150451(原因是这里调用了无参构造函数)

    原因2.效率要求这样做:

    类对象的构造顺序显示,进入构造函数体后,进行的是计算,是对成员变量的赋值操作,显然,赋值和初始化是不同的,这样就体现出了效率差异,如果不用成员初始化列表,那么类对自己的类成员分别进行的是一次隐式的默认构造函数的调用,和一次赋值操作符的调用,如果是类对象,这样做效率就得不到保障。
    注意:构造函数需要初始化的数据成员,不论是否显示的出现在构造函数的成员初始化列表中,都会在该处完成初始化,并且初始化的顺序和其在类中声明时的顺序是一致的,与列表的先后顺序无关,所以要特别注意,保证两者顺序一致才能真正保证其效率和准确性。

    为了说明清楚,假设有这样一个类:

    class foo
    {
     private:
        int a, b;
    };

    ①、foo(){}和foo(int i = 0){}都被认为是默认构造函数,因为后者是默认参数。两者不能同时出现。
    ②构造函数列表的初始化方式不是按照列表的的顺序,而是按照变量声明的顺序。比如foo里面,a在b之前,那么会先构造a再构造b。所以无论foo():a(b + 1), b(2){}还是foo():b(2),a(b+1){}都不会让a得到期望的值。
    ③构造函数列表能够对const成员初始化。比如foo里面有一个int const c;则foo(int x) : c(x){}可以让c值赋成x。
    不过需要注意的是,c必须在每个构造函数(如果有多个)都有值。
    ④在继承里面,只有初始化列表可以构造父类的private成员(通过显示调用父类的构造函数)。比如说:

    class child : public foo{};
    foo里面的构造函数是这样写的:
    foo (int x)
    {
    a = x;
    }.
    而在child里面写child(int x){ foo(x); }是通过不了编译的。
    只有把子类构造函数写作child (int x) : foo(x){}才可以。

    强调的地方:

    一 1.类里面的任何成员变量在定义时是不能初始化的。
    2.一般的数据成员可以在构造函数中初始化。
    3.const数据成员必须在构造函数的初始化列表中初始化。
    4.static要在类的定义外面初始化。
    5.数组成员是不能在初始化列表里初始化的。
    6.不能给数组指定明显的初始化。
    这6条一起,说明了一个问题:C++里面是不能定义常量数组的!因为3和5的矛盾。这个事情似乎说不过去啊?没有办法,我只好转而求助于静态数据成员。
    到此,我的问题解决。但是我还想趁机复习一下C++类的初始化:
    1.初始化列表:CSomeClass::CSomeClass() : x(0), y(1){}
    2.类外初始化:int CSomeClass::myVar=3;
    3.const常量定义必须初始化,C++类里面使用初始化列表;
    4.C++类不能定义常量数组。

    二.这里再强调一下类的初始化的顺序,应该是类成员变量的初始化不是按照初始化表的顺序被初始化的,而是按照在类中声明的顺序被初始化的。
    这是摘自:Effective C++学习笔记:初始化列表中成员列出的顺序和它们在类中声明的顺序相同.
    为什么会这样呢?我们知道,对一个对象的所有成员来说,它们的析构函数被调用的顺序总是和它们在构造函数里被创建的顺序相反。那么,如果允许上面的情况(即,成员按它们在初始化列表上出现的顺序被初始化)发生,编译器就要为每一个对象跟踪其成员初始化的顺序,以保证它们的析构函数以正确的顺序被调用。这会带来昂贵的开销。所以,为了避免这一开销,同一种类型的所有对象在创建(构造)和摧毁(析构)过程中对成员的处理顺序都是相同的,而不管成员在初始化列表中的顺序如何。

    注意:上述内容不适用于static变量,static变量应该在类的构造函数前被初始化。

    展开全文
  • C++类中常量数据成员初始化和静态成员初始化
    常量数据成员初始化原则:

    在每一个构造函数的初始化列表中初始化

    静态数据成员初始化原则:

    类内声明,类外初始化(因为它是属于类的,不能每构造一个对象就初始化一次)

    // test_max.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    using namespace std;
    
    class A
    {
    public:
    	A(int i):a(0)
    	{}
    	A():a(0)
    	{}
    	int fun(){}
    public:
    	const int a;
    	static int b;
    };
    
    int A::b=100;
    
    int main(void)
    {
    	const int size=100;
    	int a[size];
    	A ch;
    	cout<<ch.b<<endl;
    	system("pause");
    	return 0;
    }




    展开全文
  • 必须初始化初始化数据成员: 1、const修饰的成员变量; 2、引用类型的成员; 3、类对象成员(类对象的数据成员为私有成员)   拷贝构造函数参数为const引用类型; static类型的数据成员为静态成员, 他...
  • 类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化数据... 情况一、需要初始化数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);
  • 常数据成员初始化

    千次阅读 2012-07-24 16:01:45
    #include using namespace std; class Date{ public: Date(int y,int m,int d);...Date::Date(int y,int m,int d):year(y),... //是错的,常数据成员初始化后不能对其进行修改 //date.showDate(); return 0;
  • 构造函数必须初始化数据成员

    千次阅读 2017-08-10 22:07:58
    构造函数必须初始化数据成员 1.const变量 2.引用变量 3.没有默认构造函数的类类型
  • C++类成员和数据成员初始化总结

    万次阅读 2013-05-24 22:15:38
    C++为类中提供类成员的初始化列表。 类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化... 3.const数据成员必须在构造函数的初始化列表中初始化。  4.static要在类的定义外面初始化
  • 有关const成员、static成员、const static成员初始化: 1、const成员:只能在构造函数后的初始化列表中初始化 2、static成员初始化在类外,且不加static修饰 3、const static成员:类只有唯一一份拷贝,且数值不...
  • 有关const成员、static成员、const static成员初始化:1、const成员:只能在构造函数后的初始化列表中初始化(C++98); (C++11提供了类内初始化,因此内类常量可在声明类时进行类内初始化,因此该类内常量的作用...
  • 构造函数初始化必须采用初始化列表一共有三种情况, 1.... (引用)需要初始化引用成员数据class A { ... private: int a; }; class C{ C(int b); }; class B : public A { ... private: int a;...
  • 一,必须在构造函数初始化列表里进行初始化数据成员有哪些? 下面是一个自定义的Student类 class Address{}; class Student{ private: const int grade; string &name; Address addr; public: Student(int ...
  • 1.定义静态数据成员后要对静态数据成员进行初始化! 静态数据成员初始化: <数据类型><类名>::静态数据成员 = <值> 2.静态数据成员往往数私有的,静态数据成员不能直接访问,要通过定义为公有...
  • 1.实例化的过程 ...必须通过构造函数才能将类实例化,这样类的数据成员才会分配内存。 由于static成员属于类不属于各个对象,所以其不能通构造函数初始化必须通过类外初始化,才能分配内存。至...
  • C++中类的数据成员初始化,首先需要明白在类中都有哪些数据成员 const成员:也就是常量成员,它们在声明时就要初始化,因为它们为常量成员,一旦定义,就不能修改 引用成员&:引用代表的就是引用者自身,是...
  • 这种方法不在函数体内对数据成员初始化,而是在函数首部实现。这样可以减少函数体的长度。 举例如下: #include using namespace std; class Student { public: void display(); Student(int a,string b,char c)...
  • C++使用初始化列表初始化数据成员的三种情况

    万次阅读 多人点赞 2018-08-11 15:04:27
    1.分配内存,调用构造函数时,隐式/显示的初始化数据成员(构造函数列表的初始化方式不是按照列表的的顺序,而是按照变量声明的顺序同时初始化显隐数据成员); 2.进入构造函数后在构造函数中执行一般赋值与计算。...
  • C++类中静态数据成员MAP如何初始化

    千次阅读 2017-08-24 09:55:00
    在写C++时博主遇到如何对类中静态...我们可以在类中写一个静态的成员函数用于对map初始化。 CGuitarSpec.hclass GuitarSpec//吉他的部分属性 { public: string GetColor(); int SetColor(Color); string GetType()
  • 那么,是否可以这样理解: static数据成员在类外定义和初始化是为了保证只定义和初始化一次,这样编译器就不必考虑类的函数里面第一个对static变量的’=’操作是赋值还是初始化了。<br
  • 有一个类A,其数据成员如下: class A { ... private: int a; public: const int b; float* &c; static const char* d; static double* e; }; 则构造函数中,成员变量一定要通过初始化列表来初始化的...
  • 如果你想初始化一个类中的常量数据成员,只能用一种方法,在构造函数后的初始化列表中初始化; 类中的静态成员只有常量整数(不局限于int,如:short等)可以申明和定义一并出现,否则只能申明。   实例见:...
  • 特殊数据类型成员变量的初始化

    千次阅读 2011-03-31 20:53:00
    有些成员变量的数据类型比较特别,它们的初始化方式也和普通数据类型的成员变量有所不同。这些特殊的类型的成员变量包括:a. 常量型成员变量,如:const int i;b. 引用型成员变量 如:int &i;c. 静态成员变量 .如...
  • **************************数据成员初始化 *******************************************************************************************************************1、数据成员是否能在定义类的时候就初始化?...
  • 类静态数据成员的定义及初始化

    千次阅读 2017-11-16 11:25:30
    类静态数据成员的定义及初始化
  • C++类数据成员初始化

    千次阅读 2009-08-29 09:30:00
    C++为类中提供类成员的初始化列表类对象的构造顺序是这样的:1.分配内存,调用构造函数时,隐式/显示的... 3.const数据成员必须在构造函数的初始化列表中初始化。 4.static要在类的定义外面初始化。 5.数组成员是
  • 1 静态数据成员不能用参数初始化表对静态数据成员初始化 (1) 如果声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。但是静态数据成员不属于某一个对象...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 501,326
精华内容 200,530
关键字:

常数据成员必须被初始化