c++ static

来源:互联网 发布:mysql云数据库购买 编辑:程序博客网 时间:2024/06/07 20:31

//静态static局部对象只构造一次

#include "stdafx.h"

#include <iostream>

using namespacestd;

 

class A

{

public:

   A()

   {

      cout<<"CONSTRUCTION."<<endl;

   }

};

 

void fn(int i)

{

   static Aa;    //static

   cout<<i<<endl;

}

 

int main()

{

   fn(12);

   fn(14);

   fn(16);

   system("pause");

   return 0;

}

 

 

所谓临时对象,就一种无名对象,它的出现如果不在程序员的预期之下,往往会造成效率上发负担。但有时候刻意制造一些临时对象,却又可以使程序干净清爽。刻意制造临时对象的方法是,在型别名称之后直接加上一对小括号,并可指定初值,例如Shape(3,5),int(8),其意义相当于调用相应的constructor且不指定对象名称。STL最常将此技巧引用于仿函数与算法的搭配上。

 

静态常量数据成员在类内部直接初始化。如果类内含有const static int data member,那么根据C++标准规格,我们可以直接在类内部直接给与赋值所谓int泛指所有整型类别,不单只是int,还可以是long, short, char等。

 

#include <iostream>

using namespacestd;

 

class A

{

public:  

//static const成员也遵循访问控制,若想在类外访问,则必须为public

   const staticint a=3;

   const staticlong intb=45L;

   const staticchar c='C';

};

 

int main()

{

   cout<<A::a<<endl

      <<A::b<<endl

      <<A::c<<endl;

   system("pause");

   return 0;

}

注意:const成员必须在构造函数成员初始化列表中初始化,而static必须在类外初始化。而conststatic int型可以在类内初始化,但是必须也同时在.cpp文件中定义。

 

 

//a.h

#ifndef _A_CLASS_H

#define _A_CLASS_H

 

#include <iostream>

using namespacestd;

 

class A

{

private:

   conststaticintxp=23;

public:

   void display();

};

 

#endif

//a.cpp

#include "a.h"

#include <iostream>

using namespacestd;

 

constintA::xp;

 

void A::display()

{

   cout<<A::xp<<endl;

}

 

//main.cpp

#include "a.h"

#include <iostream>

using namespacestd;

 

int main()

{

   A a;

   a.display();

   system("pause");

   return 0;

}

 

初始化 const 成员和引用类型成员

初始化const成员和引用类型成员的问题,在教材中讲述初始化列表的章节应该都有讲过。

  初始化static const成员,也就是全局的静态常量,这个用到的情况比较多,想必大家都会。通常就是在类的定义中申明staticconst成员,然后在实现文件中赋予初始值,比如:

/* (#) Test.h*/

#pragma once

 

class Test

{

public:

   static constint MASK;//申明int型的MASK常量

};

 

/* (#)Test.cpp */

#include "Test.h"

 

// 定义Test::MASK常量,注意这里不需要static关键字

const intTest::MASK =0xFFFF;

 

  虽然这种static const的情况使用得最多,但有时候也会想用非static,却是const的情况。staticconst定义的常量是全局的,对该类的每一个实例(对象)甚至在全局范围都有效,而且一致。便有时候需要的常量是针对每一个实例的,每个实例都可能有同类型但不同值的常量,这时候就要用到非static,但是const的申明,如

class Test

{

public:

   const intMY_MASK;

};

 

  这种情况下,要在实例文件中像初始化static const常量一样,对其进行初始化是行不通的。

const int Test::MY_MASK = 0xFF; // 这样会报重定义错误

  况且,就算编译能通过,也不能达到我们要求的“每个对象自己的常量”的要求。

  正确的初始化是通过构造函数的初始化列表来进行,如:

class Test

{

public:

   const intMY_MASK;

   Test() : MY_MASK(0xff) {}

};

如果不是在初始化列表中对const常量进行初始化,而是在构造函数中对其赋值的话,是不成功的。很简单的道理:不能给const成员初始化。同样的道理,如果要初始化一个引用类型的成员变量,也不能在构造函数体内赋值,而只能在构造函数的初始化列表中进行初始化。

示例程序:

#include <iostream>

using namespacestd;

 

class A

{

private:

   int num;

   int &rnum; //引用

   const intcnum; //const

public:

   A(int);

   void display();

};

 

A::A(int n):num(n),rnum(num),cnum(num){}

 

void A::display()

{

   cout<<num<<endl

      <<rnum<<endl

      <<cnum<<endl;

}

 

int main()

{

   A a(3);

   a.display();

   return 0;

}


#include <iostream>
using namespace std;


/* 引用本身不是一个对象,因此不能定义指向引用的指针,但指针是对象,所以存在对指针的引用 */
void func(int *&ptri)
{
*ptri = 123;
}


/* const引用 */
void func2()
{
const int iConst = 123;


/* 错误:一定要用const的引用指向const常亮,否则就意味着iRefConstError可能会修改该值 */
//int &iRefConstError = iConst;


const int &iRefConst = iConst;
cout << "iRefConst == " << iRefConst << endl;
}


/* 一旦定义了引用,就无法令其再绑定到另外的对象,之后每次使用这个引用都是访问它最初绑定的那个对象 */
int main()
{
int i = 23;
int &refi1 = i;

cout << "i == " << i << endl;
cout << "refi1 == " << refi1 << endl;


int &refi2 = i;
cout << "refi2 == " << refi2 << endl;


refi2 = 345;


cout << "i == " << i << endl;
cout << "refi1 == " << refi1 << endl;
cout << "refi2 == " << refi2 << endl;


int iTest = 90;
int *piTest = &iTest;
//func(&iTest); //编译错误,原因未知
func(piTest);
cout << "iTest == " << iTest << endl;


func2();
system("pause");
return 0;
}


/* 成员函数通过一个名为this的额外的隐式参数来访问调用它的那个对象,当我们调用一个成员函数时,用请求该函数的对象地址初始化this 
   常量对象,以及常量对象的引用或指针都只能调用常量成员函数。


   只有当类没有声明任何构造函数时,编译器才会自动地生成默认构造函数


   不接受任何实参的构造函数,称为默认构造函数
*/