static, const, static const 与 const static

1. static const/ const static, 意义一样

namespace NdpiTransformersTest

{

class TestMain

{

public: ~TestMain();

static int run(int argc, const char** argv);

private:

static ConfigMgmtDataTypes::Config::Ptr getConfigData(const std::string& configStr);

static std::string formattedXmlString(const std::string str);

static void fromLLtoXml(const char** ll, std::string& xml);

private:

static const std::string OriginalCfgStr;

static const std::string FaultyCfgStr;

};



} // NdpiTransformersTest

PS:

  • static修饰的变量和成员函数是属于类的,而不是具体某一个对象,整个类的所有对象共用一份static修饰的变量和成员函数。
  • static修饰的变量在类的内部声明,在类的外部定义和初始化,例如:

=>这个是static变量在类TestMain的内部声明:

static const std::string OriginalCfgStr; //声明

=>这个是static变量在类TestMain的外面去定义和初始化:

namespace NdpiTransformersTest

{

const std::string TestMain::OriginalCfgStr("<timestamped-configuration>\ //定义并出示化

}
  • static静态变量,通过类名来访问,作用域为包含这个静态变量的文件中。
  • static静态变量在起作用域之外并没有释放,只是不能访问了
  • 即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。
  • static静态成员变量不能在类的内部初始化。在类的内部只是声明,定义必须在类定义体的外部,通常在类的实现文件中初始化,如:double Account::Rate=2.25;static关键字只能用于类定义体内部的声明中,定义时不能标示为static
  • 在C++中,const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数。
  • static成员函数主要目的是作为类作用域的全局函数。不能访问类的非静态数据成员。类的静态成员函数没有this指针,这导致:1不能直接存取类的非静态成员变量,调用非静态成员函数;不能被声明为virtual.

const:

  • const 常量出了它的作用域就被释放了
  • const常量在类内部声明,但是定义只能在构造函数的初始化列表中进行
  • const常量的不变性只是针对具体的类某一个对象,类的不同对象间的const常量值是可以不一样的
  • 在C++中,const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数。
  • const数据成员 只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类的声明中初始化const数据成员,因为类的对象没被创建时,编译器不知道const数据成员的值是什么。
  •  const 成员函数主要目的是防止成员函数修改对象的内容。即const成员函数不能修改成员变量的值,但可以访问成员变量。
  • 初始化
class Test  
{  
public:  
      Test():a(0){}  
      enum {size1=100,size2=200};  
private:  
      const int a;//只能在构造函数初始化列表中初始化  
      static int b;//在类的实现文件中定义并初始化  
      const static int c;//与 static const int c;相同。  
};  
  
int Test::b=0;//static成员变量不能在构造函数初始化列表中初始化,因为它不属于某个对象。  
const int Test::c=0;//注意:给静态成员变量赋值时,不需要加static修饰符。但要加const
  • 关于static、const、static cosnt、const static成员的初始化问题:
#ifdef A_H_  
#define A_H_  
#include <iostream>  
using namespace std;  
class A  
{  
public:  
      A(int a);  
      static void print();//静态成员函数  
private:  
      static int aa;//静态数据成员的声明  
      static const int count;//常量静态数据成员(可以在构造函数中初始化)  
      const int bb;//常量数据成员  
};  
int A::aa=0;//静态成员的定义+初始化  
const int A::count=25;//静态常量成员定义+初始化  
A::A(int a):bb(a)//常量成员的初始化  
{  
      aa+=1;  
}  
void A::print()  
{  
      cout<<"count="<<count<<endl;  
      cout<<"aa="<<aa<<endl;  
}  
#endif  
void main()  
{  
      A a(10);  
      A::print();//通过类访问静态成员函数  
      a.print();//通过对象访问静态成员函数  
}  

类的所有实例对象的值都一样可以用static const(const static)

class A {
public:

const static int num2 = 13; // 声明和【初始化】

};

// const int A::num2;



int main(int argc, char const *argv[])

{

cout << &(A::num2) << endl; //有编译错误,cout << A::num2 << endl;可以成功

return 0;

}

也就是说 num2 还没有定义。在取消注释后成功输出 num2 的地址。说明在 加上  const int A::num2; 后 num2 才被定义。

那为什么 num2 还没定义就可以使用了呢,其实因为 num2 是 const 常量,在生成汇编代码的时候并不是在 num2 的地址内取值,而是直接将 num2 【初始化】的时候的那个值替换掉 num2。这也就是用指针改变 const 常量的值的时候 const 常量的字面值并没有变化的原因。

  • 在类内部进行 static const 的初始化只能针对于内置类型,比如如下是会报错的:

class A { public: const static string str = "str"; }; const string str;

所以如果不是必要,一般都是采用类外初始化的形式。

  • 类内的 static const 常量的【初始化】必须用常量表达式,也就是说,这里的【初始化】值必须是一个能直接使用的值。所以如果此时要用函数返回值的话,函数应该是 constexpr 的
constexpr int fun() {

return 12;

}

class A {

public:

const static int num = fun();

};

const int A::num;

 

PS:

public对于所有的类都能访问;private只能类内部自己用,继承的子类和friend类也不能用;protected是自己和子类都能用,friend类也能使用;

const Filename getFilename() const;

前边的const表示是返回值是const, 后边的const表示这个函数是const的

explicit:

声明为explicit的构造函数不能在隐式转换中使用。

explicit构造函数是用来防止隐式转换的。请看下面的代码:

class Test1
{
public:
    Test1(int n)
    {
        num=n;
    }//普通构造函数
private:
    int num;
};
class Test2
{
public:
    explicit Test2(int n)
    {
        num=n;
    }//explicit(显式)构造函数
private:
    int num;
};
int main()
{
    Test1 t1=12;//隐式调用其构造函数,成功
    Test2 t2=12;//编译错误,不能隐式调用其构造函数
    Test2 t2(12);//显式调用成功
    return 0;
}

普通构造函数能够被隐式调用。而explicit构造函数只能被显式调用。Test1的构造函数带一个int型的参数,代码23行会隐式转换成调用Test1的这个构造函数。而Test2的构造函数被声明为explicit(显式),这表示不能通过隐式转换来调用这个构造函数,因此代码24行会出现编译错误。

 

  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值