首页 > 编程语言 >C++ day03(作用域限定符、this、static、const)

C++ day03(作用域限定符、this、static、const)

时间:2024-10-08 19:47:35浏览次数:3  
标签:const name 作用域 成员 day03 int 函数 string

目录

【1】作用域限定符::

1》名字空间

2》类内声明,类外定义

 【2】this关键字

1》概念

2》调用成员

3》区分重名的成员变量与局部变量

4》链式调用

 【3】static关键字

1》静态局部变量

2》静态成员变量

3》静态成员函数

【4】const 关键字

1》修饰成员函数

2》 修饰对象

 3》修饰成员变量


【1】作用域限定符::

1》名字空间

名字空间是一种代码的层级划分。

#include <iostream>

using namespace std;
// C++课程中几乎所有的类型(不包括基本数据类型)都在std中

int a = 1;

// 新建一个名字空间
namespace my_space {
    int a = 3;
    string s = "哈哈哈";
}

namespace my_space2 {
    int a = 4;
    string s = "嘿嘿嘿";
}

// 使用自己的名字空间
using namespace my_space2;


int main()
{
    int a = 2;
    std::cout << "你好" << std::endl;//像cout cin endl这些都属于std名字空间的内容,使用了std名字空间之后就不再需要加std::了
    cout << a << endl; // 2
    cout << ::a << endl; // 1

    // 访问my_space的内容
    cout << my_space::a << my_space::s << endl;//加上名字空间说明调用的是哪一个名字空间的变量
    // 访问my_space2的内容
    cout << my_space2::a << s << endl;//使用my_space2名字空间后就不再需要加作用域限定符来区分了

    return 0;
}

2》类内声明,类外定义

函数是可以声明定义分离的,成员函数也可以声明定义分离,把成员函数的声明放置在类内,把成员函数的定义放在类外,因为定义在类外,所以需要加上类名::来指定定义的函数是哪一个类的。

#include <iostream>

using namespace std;

class Student
{
private:
    string name;

public:
    // 类内声明
    Student(string n);
    string get_name();
    void set_name(string n);
};

// 类外定义
Student::Student(string n)//加上作用域限定符来指定是哪一个类的函数
{
    name = n;
}

string Student::get_name()
{
    return name;
}

void Student::set_name(string n)
{
    name = n;
}

int main()
{
    Student s("欢欢");
    s.set_name("刘欢");
    cout << s.get_name() << endl;

    return 0;
}

 【2】this关键字

1》概念

this在类中表示一个指针:this指针,是一种特殊的指针,保存了当前类对象的首地址(指向当前类的对象)

#include <iostream>

using namespace std;

class Student
{
private:
    string name;

public:
    Student(string n):name(n)
    {
        cout << this << endl;//输出当前对象的地址
    }

    string get_name()
    {
        cout << this << endl;//每次调用都看一下地址是多少
        return name;
    }

    void set_name(string n)
    {
        cout << this << endl;
        name = n;
    }
};



int main()
{
    //栈内存对象
    Student s("欢欢");
    cout << &s << endl;//直接取对象的地址
    s.set_name("刘欢");
    cout << s.get_name() << endl;

    cout << endl;

    //堆内存对象
    Student* s2 = new Student("hh");
    cout << s2 << endl;
    cout << s2->get_name() << endl;

    return 0;
}

2》调用成员

#include <iostream>

using namespace std;

class Student
{
private:
    string name;

public:
    Student(string n)
    {
        this->name = n;//通过this调用的对象时当前类的对象
        cout << this->get_name() << endl;
    }

    string get_name()
    {
        return this->name;
    }

    void set_name(string n)
    {
        this->name = n;
    }
};

多数情况下在类内调用成员的时候(除去有可能出现重名的情况),如果程序员不写this指针,编译器都会在成员调用时自动添加this指针。

3》区分重名的成员变量与局部变量

#include <iostream>

using namespace std;

class Student
{
private:
    string name;

public:
    Student(string name)//由于这时传过来的局部变量和成员变量重名,
//    所以这时就可以通过添加this指针来区分哪个是成员变量,哪个是局部变量
    {
        this->name = name;
    }

    string get_name()
    {
        return name;
    }

    void set_name(string name)
    {
        this->name = name;
    }
};



int main()
{
    Student s("Tom");
    cout << s.get_name() << endl;
    s.set_name("Jerry");
    cout << s.get_name() << endl;

    return 0;
}

4》链式调用

如果一个成员函数的返回值是当前类型的引用,说明这个函数支持链式调用,return的内容一定是*this。

#include <iostream>

using namespace std;

class Value
{
private:
    int value;

public:
    Value(int value)
    {
        this->value = value;
    }

    Value& add(int value)//返回值是一个Value类的引用
    {
        this->value += value;
        return *this;//所以返回的时候是一个类对象
    }

    int get_value()
    {
        return value;
    }
};



int main()
{
    Value v1(0);
    // 普通的调用方式:分步操作
    v1.add(1);
    v1.add(2);
    v1.add(4);
    v1.add(7);
    cout << v1.get_value() << endl; // 14

    cout << endl;

    Value v2(0);
    // 链式调用
    //v2.add(1)执行完之后返回的仍然是一个对象,所以可以继续调用add函数,形成一个链式结构
    cout << v2.add(1).add(2).add(4).add(7).get_value() << endl; // 14
    cout << v2.get_value() << endl; // 14

    return 0;
}

 【3】static关键字

1》静态局部变量

使用static修饰的局部变量就是静态局部变量,所在的函数第一次被调用时创建,直到程序运行结束才销毁,所有的对象共用这一个静态局部变量。

#include <iostream>

using namespace std;

class Test
{
public:
    void test_static()
    {
        int a = 1;
        static int b = 1; // 局部静态变量,这个语句只有第一次执行到的时候会执行一次,之后就不会在执行了,
        //所以在后面值发生变化之后再运行到这也不会再初始化
        cout << a++ << endl;
        cout << b++ << endl << endl;
    }
};

int main()
{
    Test t1;
    Test t2;
    t1.test_static();//1 1
    t2.test_static();//1 2
    t1.test_static();//1 3

    return 0;
}

2》静态成员变量

使用 static 关键字修饰的成员变量就时静态成员变量。

静态成员变量有以下特点:

1.非 const 修饰的静态成员变量不能再类内初始化,必须在类外初始化。

2.同一个类的所有对象共享一份静态成员变量。

3.静态成员变量可以直接通过类名调用,无需关联任何对象,因为静态成员变量在程序执行时创建,在程序结束时销毁。

#include <iostream>

using namespace std;

class Test
{
public:
    int a = 1; // 成员变量
    static int b; // 静态成员变量
};

int Test::b = 1; // 类外初始化

int main()
{
    // 通过类名直接调用静态成员变量
    cout << Test::b << " " << &Test::b << endl;

    Test t1;
    Test t2;
    cout << t1.a++ << " " << &t1.a << endl;
    cout << t2.a++ << " " << &t2.a << endl;//t1和t2的变量a是各自拥有的,所以地址不同
    cout << t1.b++ << " " << &t1.b << endl;
    cout << t2.b++ << " " << &t2.b << endl;//变量b是静态成员变量,共有的,所以t1和t2的b地址相同,和直接类名调用一样

    return 0;
}

3》静态成员函数

使用static 关键字修饰的成员函数就是静态成员函数。

静态成员函数有以下特点:

1.没有this 指针,因此不能调用非静态成员。

2.如果静态成员函数声明与定义分离,static 只需要写在声明处即可。

3.除了可以使用对象调用外,还可以直接通过类名::调用。

#include <iostream>

using namespace std;

class Test
{
public:
    int a = 1;
    static int b;

    static void func(); // 静态成员函数,声明的时候写了 static关键字
};

int Test::b = 1;

void Test::func() // 类外定义,定义的时候就不再需要写 static 关键字
{
//        cout << a << endl; 错误,a不是静态成员变量,不能被静态成员变量调用
    cout << b << endl;
}

int main()
{
    Test t;
    t.func();//类对象调用

    Test::func();//类名直接调用

    return 0;
}

【4】const 关键字

1》修饰成员函数

const修饰的成员函数,表示常成员函数,可以调用非 const 的成员变量,但是不能修改数值,不能调用非 const 的成员函数。

如果成员函数的声明与定义分离,const在声明和定义处都要写。

#include <iostream>

using namespace std;

class Test
{
private:
    string name;
public:
    void set_name(string name)
    {
        this->name = name;
    }

    string get_name() const; // 常成员函数

    void test_const() const // 常成员函数
    {
//        set_name("哈哈哈"); 错误,set_name不是常成员函数,不能调用
        cout << get_name() << endl;
        cout << name << endl;
//        name = "你好"; 错误
    }
};

string Test::get_name() const // 类外定义,即使声明的时候加了const,在定义时也要加const
{
    return name;
}

int main()
{
    Test t;
    t.set_name("再见");
    t.test_const();

    return 0;
}

 一般只要成员函数不修改属性值就使用 const 修饰,以提高代码的安全性。

2》 修饰对象

const 修饰对象表示该对象时常量对象,这样的对象的成员变量数值不可变,不能调用任何非 const 修饰的成员函数。

#include <iostream>

using namespace std;

class Test
{
public:
//    string name = "张三"; // 直接初始化可以

    string name;

//    Test(string name)
//    {
//        this->name = name; // 构造函数函数体初始化可以
//    }

    Test(string name):name(name){}

    void set_name(string name)
    {
        this->name = name;
    }

    string get_name() const
    {
        return name;
    }
};



int main()
{
    // const可以放在类型前后
    Test const t1("张三");
//    t1.set_name("你好"); 错误,set_name不是const修饰的函数,不可调用
    const Test t2("李四");
//    t2.name = "你好"; 错误
    cout << t1.get_name() << endl;
    cout << t2.get_name() << endl;

    return 0;
}

 3》修饰成员变量

const 修饰的成员变量表示常成员变量,这样的成员变量不允许被修改。

常成员变量的初始化方式有两种:

1.直接初始化

2.构造初始化列表(优先级更高)

#include <iostream>

using namespace std;

class Test
{
public:

    const string name = "张三"; // 直接初始化

    Test(){}
    Test(string name):name(name) // 构造初始化列表
    {}

//    Test(string name)
//    {
//        this->name = name; 错误
//    }

    void set_name(string name)
    {
//        this->name = name; 错误
    }

    string get_name() const
    {
        return name;
    }
};


int main()
{
    Test t0;
    cout << t0.get_name() << endl;
    Test t("王五");//由于初始化列表的优先级更高,所以“王五”覆盖掉了“张三”
    cout << t.get_name() << endl;

    return 0;
}

今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话点个关注支持一下吧! 

标签:const,name,作用域,成员,day03,int,函数,string
From: https://blog.csdn.net/dghbs/article/details/142766653

相关文章

  • 【Azure Cloud Service】创建Azure云服务时遇见分配VM资源错误: VM(s) with the follo
    问题描述创建AzureCloudService资源,遇见资源操作完成时的终端预配状态为Failed的信息。创建失败,创建的错误日志截图如下: 详细的错误信息为:{"code":"DeploymentFailed","message":"Atleastoneresourcedeploymentoperationfailed.Pleaselistdeploymentoperati......
  • Java - 15 作用域
    Java-15作用域classCat{ intage=1;//全局变量(属性),作用域是整个cat类{intnum=100;//代码块中-局部变量}publicvoidsay(){ Stringgreet="hello";//局部变量(除了属性之外就是局部变量),只能在say方法中使用System.out.p......
  • 关键字:const
    const关键字const关键字也许应该被替换成readonly(只读);1.1const修饰变量const修饰的变量,不可直接被修改——但是可以间接修改,使用指针那么const修饰变量的意义在哪里?(const修饰变量的本意是不让他修改,可是却可以绕开变量,使用指针修改,那么意义何在?)答:1.const修饰变量,这个关键......
  • const和readonly修饰的成员,静态构造函数以及对于变量的访问{get;set}
    第一,const修饰的数据类型定义:按照publicconstinttest=20;的格式进行声明,const修饰的数据类型叫做常量。注意:1访问时只能通过类名加变量名访问。      2必须在声明的时候就赋值。      3常量是不可修改的值。代码如下:usingSystem.Collection......
  • Verifying that your constructor params satisfy all assert conditions 部署测试合
     运行trufflemigrate报错***DeploymentFailed***"TestT**"hitaninvalidopcodewhiledeploying.Try:*Verifyingthatyourconstructorparamssatisfyallassertconditions.*Verifyingyourconstructorcodedoesn'taccessanarr......
  • 程序运行异常: Undefined constant"PAGE
    在使用PbootCMS时,如果遇到“Undefinedconstant'PAGE'”的错误,尤其是在后台自定义表单编辑字段时,这通常是由于PHP版本不兼容导致的问题。具体来说,某些常量或函数可能在较高版本的PHP中不再支持或行为有所变化。解决方法降低PHP版本:将PHP版本从8.0降到7.3。详细步骤检......
  • 多线程Day03
    线程优先级Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行线程的优先级用数字表示,范围从1~10Thread.MIN_PRIORITY=1;Thread.MAX_PRIORITY=10;Thread.NORM_PRIORITY=5;使用以下方式改变或获取优......
  • Day08-常量、变量、作用域
    变量、常量、作用域变量变量是可以变化的量。Java是强类型语言,每个变量都须声明类型。Java变量是程序中最基本的存储单元,要素包括变量名、变量类型和作用域。其声明格式为typevarName[=value][{,varName[=value]}];//可在同一行内为多个变量赋值,但不建议这样做//数......
  • c语言中的链接性和作用域
    什么是链接性链接性指的是标识符(如变量、函数)在多个翻译单元(通常是多个源文件)之间共享和可见的能力。链接性决定了标识符的作用范围,即它能在多大范围内被访问或引用链接性无链接性:标识符只能在局部作用域内使用,通常用于局部变量内部链接性:标识符只能在定义它的文件内使用,使......
  • JS进阶 1——作用域、解构、箭头函数
    JS进阶1——作用域、解构、箭头函数1.作用域局部作用域分为:函数作用域和块作用域函数作用域:在函数内部声明的变量只能在函数内部被访问块作用域:被{}包裹的代码成为代码块,代码块内部声明的变量外部将有可能无法访问var声明的不会产生块作用域全局作用域:<scri......