C++基础问题整理

游戏开发技术课程结合老师以及开发“俄罗斯方块”整理的 C++ 基础问题点,笔记挺基础的~

C++问题整理

1. C++的数据类型

C++ 内置如下的类型

类型 关键字
布尔型 bool
字符型 char
整型 int
浮点型 float
双精度型 double
无类型 void
宽字符型 wchar_t
#include <iostream>
using namespace std;

int main()
{
    cout << "char: " << sizeof(char) << " 字节" << endl;
    cout << "int: " << sizeof(int) << " 字节" << endl;
    cout << "float: " << sizeof(float) << " 字节" << endl;
    cout << "double: " << sizeof(double) << " 字节" << endl;

    return 0;
}

输出:

char: 1 字节
int: 4 字节
float: 4 字节
double: 8 字节

C语言是函数式编程,是过程化的,C++是面向对象编程,是基于类的


2. 类、对象、实例的区别

类 (Class),对象(Object),实例(Instance

从上面三个英文单词,其实就可以很好地区分三者。

根据前辈的指导、网上资料和个人理解,类(Class)是C++中以关键词 class 定义开头,后跟上类名,类可以类比理解现实世界例如,黑狗、白狗、花狗都是犬类,类有自己的属性和方法,类与类之间存在继承关系。

// 定义一个类,犬类
class Dog{
    public color;
    public eat(){};
}

// 声明一个对象
Dog dog1;    // dog1类别为 Dog
// 同时,dog1是Dog类的一个实例,可以有自己的颜色和行为,是一个个体存在

类提供了对象(Object)的蓝图,对象是根据类来创建的,声明类的对象

实例(Intance)是类实例化的对象,类似于现实世界中一条实际存在的狗,这条狗有自己的属性和行为。


3. 堆、栈

栈(Stack)基于一种先进后出的数据结构,由编译器自动分配释放,存放函数的参数值,局部变量等,动态分配内存。

堆(Heap),一般由程序员在编码中分配释放,比如在malloc申请分配内存空间

栈:在函数内部声明的所有变量都将占用栈内存。


4. 继承、派生

存在父类和子类,子类继承父类

一个类可以派生自多个类,从多个基类继承数据和函数

继承的类型:

  • 公有继承(public:当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
  • 保护继承(protected: 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
  • 私有继承(private:当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。

在C++中类可以多继承,形如:

// 访问修饰符继承方式是 public、protected 或 private 其中的一个,用来修饰每个基类,各个基类之间用逗号分隔
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
    <派生类类体>
};

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

虚继承:

#include <iostream>

using namespace std;
//基类

class D
{
public:
    D(){cout<<"D()"<<endl;}
    ~D(){cout<<"~D()"<<endl;}
protected:
    int d;
};

class B:virtual public D
{
public:
    B(){cout<<"B()"<<endl;}
    ~B(){cout<<"~B()"<<endl;}
protected:
    int b;
};

class A:virtual public D
{
public:
    A(){cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}
protected:
    int a;
};

class C:public B, public A
{
public:
    C(){cout<<"C()"<<endl;}
    ~C(){cout<<"~C()"<<endl;}
protected:
    int c;
};

int main()
{
    cout << "Hello World!" << endl;
    C c;   //D, B, A ,C
    cout<<sizeof(c)<<endl;
    return 0;
}

5. 多态

当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态,C++ 在调用成员函数时,会 根据调用函数的对象的类型来执行不同的函数

#include <iostream>
using namespace std;

class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      virtual int area()
      {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};

class Rectangle: public Shape{
   public:
      Rectangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      {
         cout << "Rectangle class area :" <<endl;
         return (width * height);
      }
};

class Triangle: public Shape{
   public:
      Triangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      {
         cout << "Triangle class area :" <<endl;
         return (width * height / 2);
      }
};
// 程序的主函数
int main( )
{
   Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);

   // 存储矩形的地址
   shape = &rec;
   // 调用矩形的求面积函数 area
   shape->area();

   // 存储三角形的地址
   shape = &tri;
   // 调用三角形的求面积函数 area
   shape->area();

   return 0;
}

输出:

Rectangle class area
Triangle class area

6. 字符型指针变量与字符数组的区别

设有定义字符型指针变量与字符数组的语句如下:

char *pc ,str[1000];

在内存分配上,系统将为字符数组str分配1000个字节的内存单元,用于存放1000个字符。 而系统只为指针变量pc分配4个存储单元,用于存放一个内存单元的地址。

char str[ ] ="I am a student ! " ,s[2000];
char *pc="You are a student ! " ;

对于字符数组,是将字符串放到为数组分配的存储空间去, 而对于字符型指针变量,是先将字符串存放到内存,然后将存放字符串的内存起始地址送到指针变量pc中。

字符数组只能对其元素逐个赋值,而不能将字符串赋给字符数组名。对于字符指针变量,字符串地址可直接赋给字符指针变量。

str="I love China! "; //字符数组名str不能直接赋值,该语句是错误的。
pc="I love China! ";  //指针变量pc可以直接赋字符串地址,语句正确
  1. 分配内存 分配1000个单元 分配4个单元。
  2. 赋值含义 字符串放到数组存储空间 先将字符串存放到内存,将存放串的首地址送到pc中。
  3. 赋值方式 只能逐个元素赋值 串地址可赋给pc
  4. 输入方式: 串直接输入字符数组 不能将字符串直接输入指针变量
  5. 值的改变: 字符数组首地址不能改变 指针变量的值可以改变

从实际开发“俄罗斯方块”小游戏的过程中,遇到的问题也远不止如此,这些只是部分基础并且常常设计得到的情景,一个APP往往是从整体考虑,编程语言和数据结构为舟,算法是灵魂。

发表评论 / Comment

用心评论~