变量(定义 初始化)、临时变量

声明与定义
变量的声明(如:extern int a;声明外部变量)告诉编译器变量名字与类型;
变量的定义:为变量分配存储空间,此时也可以给定初始值;
函数的声明:告诉编译器有这么一个函数;
函数的定义:实现函数,简言之就是带有{ };
 
与结构体一样,类只是一种复杂数据类型的声明,不占用内存空间。
而对象是类这种数据类型的一个变量,或者说是通过类这种数据类型定义了一个变量(对象),是占用内存空间的。
calss Point{
};
 
Point t1; // 将调用构造函数
Point *t1;// 不调用构造函数
 
声明一个指针 int *p;表示*p的类型为int,p是指向int类型的指针;(即p为int* ; *p为int)
定义 int *p 时,p位于栈区,占有内存空间是系统分配,系统将给定一个随机地址(不确定地址)给p;
void main_5()
{
    int *p;     
    printf("0x%x \n", p);
    *p = 5;
    printf("%d \n", *p); // 若无上句的赋值(给确切的内存地址),将非法访问内存,程序奔溃
}
 
 
 
 
 
二、临时变量的产生
临时变量只在调用期间有效,有三种方式产生: 函数返回时、类型转换时、形式参数为const时
1、函数返回时,以值或是指针形式返回时;
int sum(int a,int b)
{
    return a + b;//编译器会将结果a+b的值拷贝给临时变量,最终返回的是临时变量;
}
2、在进行 强制类型转换时;
double a = 10.5;
cout << (int)a ;// 在强转时,一定生成临时变量,原始数据本身并没有改变。
cout << a;
3、函数形参为const来保护原始数据;
 
 
 
 
三、初始化
C++的初始化方式:默认初始化、值初始化、直接初始化、拷贝初始化、列表初始化;
 
默认初始化
1、未初始化的 全局内置类型(int、double)变量;
2、类 类型,都会执行默认构造函数;如string、vector<int>;
 
值初始化
值初始化是值使用了初始化器(即使用了圆括号或花括号)但却没有提供初始值的情况;
vector<int> v1(10);//10个元素,每个元素的初始化为0
vector<string> v2(10);//10个元素,每个元素都为空
vector<int> v4(10, 1);//v3有10个元素,每个的值都是1
vector<int> v3{10};//v2有1个元素,该元素的值是10
vector<int> v5{10, 1};//v4有2个元素,值分别是10和1
int *p = new int();
 
 
直接初始化
直接初始化是指采用小括号()而不使用等号=的方式进行变量初始化;
string str1(10,'9');//直接初始化
string str2(str1);//直接初始化
 
 
拷贝初始化
使用等号(赋值号=)进行初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去,拷贝初始化通常使用拷贝构造函数来完成。拷贝初始化看起来像是给变量赋值,实际上是执行了初始化操作,与先定义再赋值本质不同。
int a = 0;
int a = {0};
string str1 = "hello";
string s=string("123456");
 
初始化列表
为C++11采用的初始化方式,使用{}进行初始化操作,下列三种情况需要用到初始化成员列表:
1、 类的数据成员中含有不带默认构造函数的 对象 (包括在继承时显示调用父类的构造函数对父类成员初始化);
2、 类的数据成员中含有 const修饰类型 的或 引用类型 ;(因为这两种对象要在声明后马上初始化);
3、 子类初始化父类的私有成员
vector<int> v4{1, -2, 3, 10, -4}; // 等价于 v4 = {1, 2, 3, ....} 
int b[5]{10,20,30,40,50}; // a[] = {10,20,30,40,50};
 
class People{
    public:
        People(string n="", int a = -1) : age(a)name(n){} // 列表初始化
    private:
        string name;
        int age;
};
 
注意:初始化列表中变量的执行顺序是由成员变量的声明顺序来决定的,上述并不先执行age(a),而是先执行name(n);
 
【举例1】
class A {
    ...
    private:
       int &a;
};
class B : public A {
    ...
    private:
         int a;
    public:
         const int b; // 数据成员中含有const修饰类型的或引用类型,必须通过初始化列表来初始化;
         A c; // 数据成员中含有不带默认构造函数的对象,必须通过初始化列表来初始化;
         static const char* d;
         A* e;
};
 
 
 
类对象的显式初始化
Data data1(2019,9,22);//显式初始化,直接调用构造函数
Data* b = new Data(2019,9,22);//显式初始化,直接调用构造函数,使用delete时析构
Data p = Data(2019,9,22);//显式初始化,直接调用构造函数,没有临时对象,作用域结束时析构
Data B(data1);//显式初始化,调用拷贝构造函数,作用域结束时析构
 
 
类对象的隐式初始化
Data b = a;//用一个对象隐式初始化另一对象,调用拷贝构造函数,作用域结束时析构
 
 
 
 
 
C++11  initialize_list类模板( 初始化类模板 #include<initalize_list>
 
#include <iostream>
#include <vector>
class MyNumber
{
public:
    MyNumber(const std::initializer_list<int> &v) {// C++11允许构造函数和其他函数把初始化列表当做参数。
        for (auto itm : v) {
            mVec.push_back(itm);
        }
    }
    void print() {
    for (auto itm : mVec) {
        std::cout << itm << " ";
    }
  }
private:
    std::vector<int> mVec;
};
 
int main()
{
    MyNumber m{ 1, 2, 3, 4 }; // calls initializer_list
    m.print();  // 1 2 3 4
    
    MyNumber m2{ 10, 20, 30, 40 }; // calls initializer_list
    m2.print();  // 10 20 30 40
 
    return 0;
}
 
 
 
 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值