首页 > 编程语言 >C++基础知识

C++基础知识

时间:2024-09-05 20:49:40浏览次数:13  
标签:变量 name int C++ 基础知识 myclass 构造函数 函数

1、基本概念

1.1 引用类型(reference)

         对一个数据可以使用" 引用 " ( reference )类型,这是 C++ 对 C 的一个重要扩充,引用是一种新的变量类型,它的作用是为一个变量起一个别名
int a; int &b = a;
        在声明变量 b 时变量 a 的引用后,在它们所在函数执行期间,该引用类型变量 b 始终与其代表的变量 a 相联系,不能再作为其他变量的引用( 别用 ) ,意思是 " 企图使 b 又变成其他变量的引用是不行的 " 。         C++之所以增加引用类型,主要是把它作为函数参数,以扩充函数传递数据的功能。指针变量要另外开辟内存单元,其内容是地址,而引用变量不是一个独立的变量,不单独占内存单元。这种传递方式比使用指针比变量简单、直观、方便。使用变量的引用,可以代替部分指针的操作。引用不仅可以用于变量,也可以用于对象。 示例代码:
#include <iostream>
using namespace std;

//typedef //类型重定义
/*
    C语言使用指针存储变量的地址 可以由指针对变量操作

    C++语言弱化指针的概念,引入了 引用 的概念
    格式:类型 &引用变量名 = 需要引用的变量
    [C语言中的空指针NULL C++中空指针nullptr]

*/
void exchange(int &x, int &y);
int main()
{
    /*
        int a = 10;
        int *p = &a;        //int*类型的指针p指向int类型变量
        *p = 50;            //将a改为50

        int &b = a;
        cout << b << endl;  //引用就是给变量起别名,引用必须和要引用的变量是同类型

        char m = 'A';
        char &n = m;
        cout << n << endl;  //通过引用也可以修改原有变量的内容
        n = 'a';
        cout << n << endl;
    */

    int a = 10;
    int b = 40;
    int &c = a;

    //c = b;          //引用无法修改指向
    exchange(a, b);
    cout << a << "  " <<b << endl;
    return 0;
}

/* 引用的产生主要是为了函数传参(传参类的对象) */
void exchange(int &x, int &y){
    int temp = 0;
    temp = x;
    x = y;
    y = temp;
}
/*
    引用 和 指针的区别
    1. 指针是一个变量,占8字节(64系统),系统会为其分配至地址
        引用不是变量,不占空间,只是原本变量的别名
    2. 指针可以修改指向,但是引用一旦定义就无法修改指向,因为依赖于变量存在
    3. 指针定义的时候可以不初始化,但是引用定义的同时必须初始化
*/

 2.2 内置函数(inline-function

        C++提供一种提高效率的方法,即在编译时将所调用函数的代码直接嵌入到主调函数中,而不是将流程转出去。这种嵌入到主调函数中的函数称为内置函数(inline function ),又称内嵌函数。指定内置函数的方法很简单,只需在函数首行的左端加一个关键字 inline 即可。         内置函数中不能包括复杂的控制语句,如循环语句和 switch 语句。         应当说明:对函数作 inline 声明,只是程序设计者对编译系统提出的一个建议,也就是说它是建议性的,而不是指令性的。并非一经指定为 inline ,编译系统就必须这样做。编译系统会根据具体情况决定是否这样做,例如对前面提到的包含循环语句和 switch 语句的函数或一个递归函数是无法进行代码置换的,又如一个 1000 行的函数,也不大可能在调用点展开。此时编译系统就会忽略 inline 声明,而按普通函数处理。         总结,只有那些规模较小而又被频繁调用的简单函数,才适合于声明为内置函数。 示例代码:
#include <iostream>
using namespace std;

/*
	内置函数 / 内联函数 / 内嵌函数
	
	称以下体积较小并且逻辑简单,调用次数较多的函数为内置函数
	如果函数体内部逻辑复杂,while,for,if等判断循环分支语句都不建议设置为内置函数

	格式:在函数名称前加上关键字inline
		[加上关键字知识给编译器提建议,具体是否将函数设置为内置函数还是要看编译器的判断结果]
		[如果函数过于复杂,编译器将函数看作普通函数对待]
*/

/*

如果在程序中要重复多次的执行简单动作,例如函数
跳转时间 1ms
函数执行时间 0.5ms
函数如果在程序中调用100次 跳转时间一共就100ms
如果函数体转换时间花费较多可以将函数设置为内联函数
 实现过程:

	将实参传给形参,将形参拷贝到函数体内部
	再将函数体内部执行程序替换到主程序中调用该函数的位置

*/
inline void printInfo(string name, int id){
	cout << name << "  " << id << endl; 
}

int main(){
	printInfo("A", 1000);
	printInfo("B", 1001);
	printInfo("C", 1002);

	
	cout << "D" << "  " << 1003 << endl; 
	//....

	return 0;

2.3函数重载(function-overloading

        C++允许用同一个函数名定义多个函数,这些函数的参数个数和参数类型不同,这就是函数的重载。即对一个函数名重新赋予它新的含义,使一个函数名可以多用。         重载函数除了允许参数类型不同以外,还允许参数的个数不同。

2.4函数模板(function-template)

        C++提供了函数模板。所谓的函数模板,实际上是建立一个通用函数,其函数类型和参数类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板,凡是函数体相同的函数都可以用这个模板来代替,不必定 义多个函数,只需再模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
通用类型定义 
template <typename XXX> 
template 的含义是"模板",
<>中先写关键字 typename 或 class ,后边跟一个类型参数 
XXX,类似标识符, 是一个虚拟的类型名

2.5 动态内存分配

        在软件开发的过程中,常常需要动态地分配和撤销内存空间、例如对动态链表中节点的插入和删除。C 语言中 是利用库函数 malloc 和 free 来分配和撤销内存空间的,而 C++ 则提供了较为简便且功能较强的运算符 new 和 delete 来取代 malloc 和 free 函数。          需要注意的是,new 和 delete 是运算符,不是函数,因此执行效率更高。为了与 C 语言兼容,C++仍保留了malloc 和 free 函数,但不建议使用,更推荐使用 new 和 delete
/* 开辟一个存放整型的存储空间,返回一个指向该存储空间的地址(指针) */ 
int *p = new int; 
/* 开辟一个存放整型的存储空间,并指定该整数的初值为 100 */ 
int *p = new int(100); 
/* 开辟一个存放二维整型数组的空间,返回首元素的地址 */ 
int (*p)[4] = new int[5][4]; 
new 运算符使用的一般格式为:new 类型(初值) 用 new 分配数组空间时不能指定初值。 
如果由于内存不足等原因而无法正常分配空间,则 new 会返回一个空指针 NULL,用户可以根据该指针的值判 断分配空间是否成功。 delete 运算符使用的一般格式为:delete []指针变量 对基本数据类型的申请可以直接释放。 
如果是类似"char *pt = new char[10]"申请的字符数组空间(构造数据类型空间),释放时应在指针变量前 加一对方括号,表示是对数组空间的操作:delete []pt;
#include <iostream>
using namespace std;

/*
    C语言中使用malloc free进行堆区空间的申请和释放
        void * malloc()

    C++ 使用new delete
*/

typedef struct Person{
    string name;
    int age;
}P_t;
int main(){
    int *p = new int;	//申请4字节空间
    int *q = new int(50);	//申请4字节空空间的同时初始化
    *p = 100;
    cout << *p << endl;		//100
    cout << *q << endl;		//50

    int *t = new int[10];	//申请10个连续的4字节空间
    for(int i=0; i<10;i++){	//循环初始化
        *(t+i) = i;
    }
    for(int i=0; i<10;i++){
        cout << *(t+i) << endl;
    }

    int *T = new int[5]{8,5,2,3,0};	//申请同时初始化
    for(int i=0; i<5;i++){
        cout << *(T+i) << endl;
    }

    struct Person *L = new P_t{("Zhang"), 90};

    delete p;
    delete q;
    delete []t;           //动态申请的连续空间在释放时要加上[]
    delete []T;
    delete L;

    return 0;
}

2、概念升级

2.1 类的定义和使用

        定义类需要使用关键字 class ,然后指定类的名称。类的主体是包含在一对花括号中,其中包含成员变量和成员函数。定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。
class 类名 
{访问修饰符: // 
属性 type name; // 
方法 type method(); };
// 和结构体类型定义相同 类的定义需要以分号结尾
        类用来创建对象,对象中的数据成员可以使用运算符"." 进行访问,类不仅可以创建对象变量,也可以创建对象指针,对象指针访问数据成员则使用运算符" -> " ,这一点和结构体类似。 示例代码:
#include <iostream>
using namespace std;
/*
 * 在C语言结构体中不能定义或者实现函数,在c++中结构体可以
 * 在类中也可以直接定义以及实现函数
 *  类  class
 *  类中的内容:分为两种变量(属性)和函数(方法)
 *  定义类的格式:
 *      class 类名{
 *          //类中的成员函数以及成员变量
 *      }
 *
 *  类中成员有三种访问修饰符 public protected private
 *  public:公开成员,类内类外都可以访问
 *  protected: 保护成员,类内可以访问,类外不能访问,但是继承类可以访问
 *  private:私有成员,类外不可访问,继承类也不能,友元类和友元函数可以访问
 *
 *  类中如果没有任何访问修饰符,那么全部成员是私有的
 */
class myclass{
public:
    string name;
    int age;
    friend void friendFunc();           //声明友元函数,此类中的私有成员在友元函数种可以访问问
    friend class fclass;
    void inputInfo(string t_name, int t_age){
        name = t_name;
        age = t_age;
    }
    void ouptInfo(){
        cout << "name=" + name << "  " << "age=" << age <<endl;
    }
private:
    int private_num;
};

void friendFunc(){
    myclass user2;
    user2.private_num = 100;   //在友元函数种访问私有成员
}

int main()
{
    //使用自定义的类定义对象 -- 实例化类
    myclass user;

    //调用成员函数对成员变量赋值
    user.inputInfo("Zhang", 20);
    user.ouptInfo();

    return 0;
}

2.2构造函数/析构函数

myclass.h:

#ifndef MYCLASS_H
#define MYCLASS_H
#include <iostream>
using namespace std;
/*
 * 构造函数和析构函数由系统生成并调用,不由用户调用
 *  构造函数在对象生命周期开始的时候被调用
 *  析构函数在生命周期结束时候被调用

*/

class myclass{
public:
    //无参构造函数-默认
    myclass();             //构造函数函数名和类名相同,没有返回值,可以传参数,可以被重载
    ~myclass();            //构造函数函数名是类名加上~,没有返回值,不可以传参数,不可以被重载
                           //如果在类内显式声明构造函数就要实现

    myclass(string name, int age);              //构造函数重载
    myclass(string name, int age, char sex);    //构造函数重载
    myclass(const myclass &obj);                //拷贝构造函数-将另外一个对象的全部内容拷贝给当前的对象
                                                //编译器也会自动生成拷贝构造函数可以直接使用
    void outputInfo(){              //该函数为公开函数,可以在类外访问该函数,间接访问或者修改私有成员
        cout << name << endl;
        cout << age << endl;
        cout << sex <<endl;
        //this->name; //在普通成员函数内可以使用this
    }
    static int num;     //静态成员变量

    static void static_func(){
        //cout << this << endl;     //静态成员函数中不能使用this
        cout << "staic func " << endl;
    }

protected:
private:		//私有成员 类外无法访问 [友元函数可以]
    string name = "Zhang";
    int age;
    char sex;
};


#endif // MYCLASS_H

myclass.cpp:

#include "myclass.h"

myclass::myclass(){
  cout << "无参构造函数:" << name <<"生命周期开始" <<  endl;
}

myclass::~myclass(){
  cout << "析构函数:" << name <<"生命周期结束" <<  endl;
}

//构造函数重载
myclass::myclass(string name, int age){
    this->name = name;              //在函数体内部初始化成员变量
    this->age = age;
    cout << "有参构造函数:" << name <<"生命周期开始" <<  endl;
}
//this指针:只能在类内的成员函数中使用,指向调用成员函数的对象,是一个无类型的指针(静态成员函数中不能用this指针)


//构造函数重载--形参初始化列表  -> 要初始化的成员名称(形参) 以逗号分隔开
myclass::myclass(string name, int age, char t_sex) : name(name), age(age), sex(t_sex){
    cout << "有参构造函数:" << name <<"生命周期开始" <<  endl;
}

//拷贝构造函数 自定义并实现
myclass::myclass(const myclass &obj){
    name = obj.name;
    age = obj.age;
    sex = obj.sex;
}

main.cpp:

#include "myclass.h"

//在c++源文件种,可以定义结构体在结构体定义并实现函数
//结构体种的函数默认的访问修饰符public
//也可以使用其他两个修饰符

//结构体类型    变量
//类 (数据类型) 对象(变量)

int myclass::num = 80;			//静态成员函数必须在类外部定义一次

int main()
{
/*
    myclass u1;             //对象的生命周期开始
    myclass u2("Wang", 50); //有参构造函数--重载
    u2.outputInfo();

    myclass u3("Liu", 10, 'm');  //有参构造函数--重载
    u3.outputInfo();

    myclass u4(u3);         //拷贝 构造函数
    u4.outputInfo();
*/
    myclass user;
    myclass::static_func();         //静态成员变量以及静态成员函数访问方式
                                    //1. 使用类定义对象,通过对象进行访问
                                    //2. 直接使用类加上访问限定符访问静态成员(变量/函数)
    cout << myclass::num++ << endl; //80
    cout << myclass::num++ << endl; //81
    cout << myclass::num << endl;   //82

    return 0;
}

2.3继承/抽象类/虚函数/多态

#include <iostream>
using namespace std;

/* 基类 父类 */
class Parent{
public:                 //类内外
    string name;

    Parent(){
        cout << "父类的无参构造函数" << endl;
    }
    Parent(int num){
        this->private_num = num;
        cout << "父类的构造函数重载" << endl;
    }

    void outputInfo(){
        cout << name << endl;
        cout << age << endl;
    }

    virtual void buy(){
        cout << "父类 全价" << endl;
    }

protected:          //只能在类内访问和派生类中访问
    int age;

private:            //只能在类内访问 和 友元函数内
    int private_num;
};


/* 派生类 子类 */
//格式 class 类名 : 继承方式 父类名称{}
class Child : public Parent{
    //默认存在基类中公开的成员
    //可以再定义一些派生类的成员
public:
    Child(){
        cout << "子类的无参构造函数" << endl;
    }
    virtual void buy(){         //覆盖  override重写
        cout << "子类 半价" << endl;
    }
};

class abclass{
public:
     virtual void abfunc() = 0;            //纯虚函数  含有纯虚函数的类叫做抽象类-无法实例化的类
};

//如果继承自抽象类的派生类不重写基类中的纯虚函数,那么派生类也是抽象类,无法实例化
class son_abclass: public abclass{          //抽象类的派生类
public:
    virtual void abfunc() override{
        cout << "这是派生类的重写" << endl;
    }
};

void func(Parent &p){
    p.buy();
}

//多态:不同对象调用同一接口时有不同的动作
int main()
{
    //使用派生类定义对象  可以直接访问基类中的公开成员
    //Child child1;
/*
    Parent p1;      //基类对象
    Child c1;       //派生类对象

    Parent *P;
    P = &p1;
    P->buy();		//如果基类和派生类没有加上virtual,那么此处和79行P->buy()都会调用基类中的buy函数

    P = &c1;
    P->buy();		//如果在基类以及子类中的成员函数都没有使用virtual进行修饰==没有满足多态
    				//那么调用函数时会根据指针的类型调用,也就是说基类的指针指向子类成员(此时指针类型为基类)
    				//也会调用基类中的成员函数而不是派生类的成员函数
*/

/*
    Parent p1;      //基类对象
    Child c1;       //派生类对象

    func(p1);
    func(c1);

*/

    return 0;
}

(仅供参考学习)

标签:变量,name,int,C++,基础知识,myclass,构造函数,函数
From: https://blog.csdn.net/Z102704/article/details/141827815

相关文章

  • C++学习笔记----6、内存管理(二)---- 数组指针的双向性
            你可能已经看到指针与数组之间的一些重叠。自由内存空间分配的数组由其第一个元素的指针进行访问。栈上的数组通过使用数组语法([])或者正常变量声明来访问。你还会看到的是,其重叠不仅如此,指针与数组有更复杂的关系。1、数组退化至指针        自由内......
  • C++入门基础知识50——【关于C++数字】之C++ 数学运算
    成长路上不孤单......
  • 终于使用c++、结构体,函数实现简单数组元素的插入
    includeusingnamespacestd;//定义结构体structMyArray{intarr[100];//数组,假设最大长度为100intn;//数组当前元素数量};//输入函数voidscanf(MyArray&myArray,int&x,int&y){cin>>myArray.n;for(inti=0;i<myArray.n;i++){cin>>my......
  • 深度解析C++中函数重载与引用
    ......
  • C++ STL queue容器——队列
    queue容器基本概念queue是一种**先进先出的数据结构,它有两个出口,queue容器允许从一端新增元素,从另一端移除元素。queue容器没有迭代器,所有元素进出都必须符合“先进先出”条件,只有顶端的元素才有机会被外界取用,所以也不提供遍历功能。queue容器常用操作构造函数queue<T>qu......
  • c++遍历数组的多种方式
    方法一:普通的for循环for(inti=0;i<sizeof(a)/sizeof(a[0]);i++){cout<<a[i]<<"";}方法二:指针数组int*p[len];for(inti=0;i<len;i++){p[i]=&a[i];cout<<*p[i];}———————————————......
  • 铜线电阻基础知识科普篇
    铜线是电气工程中最常用的导电材料之一。由于其优异的导电性能和良好的机械特性,铜线在电力传输、电子设备和通信等领域具有广泛的应用。理解铜线的电阻特性有助于设计和优化电气系统,提高能效并确保安全运行。一、铜线的基本特性导电性铜线的导电性是衡量其传输电流能力的重要指标。......
  • Qt C++设计模式->策略模式
    **策略模式(StrategyPattern)**是一种行为型设计模式,它定义了一系列算法,将每一个算法封装起来,并使它们可以互相替换,策略模式让算法可以独立于使用它的客户端而变化。这意味着,客户端可以根据需要动态选择使用哪种算法,而不需要修改算法的实现。策略模式的主要组成部分策略接......
  • C++ STL stack容器——栈
    stack容器基本概念stack是一种先进后出的数据结构,它只有一个出口,形式如下图所示。stack容器允许新增元素,移除元素,取得栈顶元素,但是除了最顶端外,没有任何地方可以存取stack的娶她元素。换句话说,stack不允许有遍历行为。元素推入栈的操作称为push,将元素推出栈的操作称为pop。st......
  • C++程序的发布部署方式及缺失依赖库dll的解决方法
    主要对Windows平台上C++项目开发过程中库目录进行梳理及程序发布要注意的相关事项进行总结,希望对其他开发者有一定的借鉴意义。1.问题的提出在最近的项目中,主要工作是为SketcchUp平台开发基于Ruby的扩展功能库,这种库文件是以.so为后缀的形式提供,用C++语言来编写实现。当我在自己......