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

声明与定义
变量的声明(如: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;
}
 
 
 
 
 
 
 
 
 
 
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读