admin管理员组文章数量:1122852
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行会出现编译错误。
本文标签: staticconststatic const 与 const static
版权声明:本文标题:static, const, static const 与 const static 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1686863296a43057.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论