跳至主要內容

类的内容 - 总结

LincZero大约 6 分钟

类的内容 - 总结

访问控制

Const 成员函数(访问器方法)

const成员函数 / 常量成员函数

  • 使用场景

    • 举例:const Stock land = Stock("LLL"); land.show();中,第二条语句会被拒绝
  • 使用

    • 声明时在后面加cosnt,如void stock::show() const;。这种函数称为const成员函数

    • 设计思路(猜的)

      • 一般函数的解决方案是在参数列表中添加const,但这里实例本身是隐式参,不在参数列表里

      • 既然参数列表里不能加,函数前面的const又表示返回值的类型,于是这里的const就被设计成放在后面了

      • 用来表示在该成员函数中,对象本身的传入类型是const

  • 作用

    • 一是能规定一些函数当对象实例被声明为const时不可用

      即被声明未const类型的对象实例能访问const成员函数而不能访问非const成员函数

    • 二是使被声明为const的对象实例仍能访问其中的函数(主要作用)

    • 三是防止数据被某些成员函数改变

参考:https://www.cnblogs.com/cthon/p/9178701.html

类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员**(准确地说是非静态数据成员)**作任何改变

在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const

  • (1)有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员; 没有 const 修饰的成员函数,对数据成员则是可读可写的。
  • (2)除此之外,在类的成员函数后面加 const 还有什么好处呢? 那就是常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。

const成员变量 / 常量成员变量

和const成员变量之间没有什么关系

  • const成员变量:这里的const指的是 “常量”
  • const成员函数:这里的const着重指 “不修改”
    • 非const/const成员函数,都能调用 非const/const成员变量

const对象 / 常量对象

总结

  1. const对象只能调用const成员函数,不能调用非const成员函数

    非const对象可以调用const成员函数,自然也能调用非const成员函数

  2. 非const成员函数可以调用const成员函数

    反过来则不行,const成员函数不能调用非const成员函数

  3. 非const/const成员函数 都能调用 非const/const成员变量他们之间没什么关系

Static 静态成员函数

静态成员函数 = 成员函数 x 静态成员变量

说明

  • 静态成员变量,一般与静态成员函数一起使用
  • 静态成员变量和静态成员函数,均不与对象实例相关,可以在不创建对象的情况下使用
  • 静态成员函数:只能使用静态成员变量,而不能使用其他成员变量

static成员变量 / 静态成员变量

  • 使用
    • 注意:不仅仅只是在前面加static关键字
    • 使用静态成员变量时,还需要在类实现文件中进行初始化,比如
      • .h:static PluginManager *m_instance;
      • .cpp:PluginManager* PluginManager::m_instance;(是否初始化值均可,但一定要在cpp声明)
      • 如果没有初始化,QT中会报错:LNK2001: 无法解析的外部符号 "xxx: static class xxx
      • 若不使用,比如只是为了使用其析构函数(如在类中嵌套垃圾回收的类),则不需要初始化

static成员函数 / 静态成员函数

  • 说明
    • 可将成员函数声明未静态的(静态就意味着存储在全局/静态区,且只有一个备份)
  • 使用
    • 定义:在前面加关键字static,如static int HowMany(){return num_strings;}
    • 使用:例如int count = String::HowMany();(不使用成员运算符)
    • 补充:可以在不创建对象的情况下直接使用静态成员函数,如 pluginManager = PluginManager::instance(); 如果非静态成员函数用这种写法的话会报错 call to non-static member function without an object argument(在没有对象参数的情况下,调用了一个非静态成员函数)
  • 注意
    • 静态成员函数不与特定的对象相联,只能使用静态数据成员而不能使用类的其他成员
    • 静态成员函数与普通成员函数的根本区别在于:普通成员函数有 this 指针,可以访问类中的任意成员 而静态成员函数没有 this 指针,只能访问静态成员

static对象 / 静态对象

单例模式会用到 static对象,将构造函数放入private,然后将static对象的创建放入instant 方法中。 那么在调用 instant 方法之前,该static对象不存在。调用 instant 方法后,该static对象一直存在至程序结束。

总结

  • static成员函数非static成员函数其实能互相调用。但static函数调用非static函数需要一点技巧,见:https://www.cnblogs.com/rickyk/p/4238380.html
  • static对象和static成员函数或非static成员函数 没有什么关系
  • static成员变量和static成员函数或非static成员函数也 没有什么关系

const static / conststatic

这个应该只能修饰成员变量,至于成员函数应该无法修饰(再说成员函数的const和static分别在括号的后面和函数声明的最前面,不在一起的),对象应该也无法修饰

const static / conststatic 成员变量

参考:https://blog.csdn.net/lp10031312/article/details/79512165

const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间

static表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。

  • const成员函数主要目的是防止成员函数修改对象的内容
  • static成员函数主要目的是作为类作用域的全局函数
class Test{  
public:  
    Test():a(0){}  
    enum {size1=100,size2=200};  
private:  
    const int a;		// 只能在构造函数初始化列表中初始化  
    static int b;		// 在类的实现文件中定义并初始化  
    conststatic int c;	// 与 static const int c;相同。  
};  
   
int Test::b=0;//static成员变量不能在构造函数初始化列表中初始化,因为它不属于某个对象。  
cosnt intTest::c=0;//注意:给静态成员变量赋值时,不需要加static修饰符,但要加cosnt。