1、一、类型、返回值类型 二、参数表、函数重载
2、一、实例化 二、实例化的类型或类类是对象的蓝图,对象是类的实例化
3、const
4、一个 两个
5、一、公有继承 二、私有继承、保护继承
6、抽象类、实例化对象
7、函数模板、类模板
8、try、catch、throw
9、流插入运算符、流提取运算符
10、可以、可以
11、析构函数
程序阅读题:
#include <iostream>
int m = 10;
void a(int n) {
n = 15 / n;
m = m / 2;
}
int main() {
int n = 3;
a(n);
std::cout << "m=" << m << std::endl;
std::cout << "n=" << n << std::endl;
return 0;
}
这段代码的功能如下:
- 包含了iostream头文件以使用输入输出流。
- 定义了一个整型变量m并初始化为10。
- 声明了一个函数a,接受一个整型参数n。
- 在函数a中,将15除以参数n的值赋给n,然后m除以2的结果赋给m。
- 在主函数main中,定义了一个整型变量n并初始化为3。
- 调用函数a,并传入参数n。
- 使用cout输出m的值,并换行。
- 使用cout输出n的值,并换行。
- 返回0,表示程序正常结束。代码的执行流程如下:
- 声明一个整型变量m并初始化为10。
- 定义函数a,接受一个整型参数n。
- 在函数a中,将15除以参数n的值赋给n,然后将m除以2的结果赋给m。
- 在主函数main中,定义一个整型变量n并初始化为3。
- 调用函数a,并将参数n的值传入。
- 使用cout输出m的值为5,并换行。
- 使用cout输出n的值为3,并换行。
- 返回0,表示程序正常结束。最终输出结果为:
m=5
n=3
这段代码的功能是对变量m和n进行一些计算操作,并输出结果。
答案:m = 5,n = 3; 过程:a(3); ----> { n = 15/3; m = 10/2; } n是在main()函数中声明的,n = 3,所以n = 15/3 = 5,只在函数a()的作用域中n = 5,但是a()是 void 类型,没有返回值,因此,回到main()函数中后,n仍然等于3。而m是全局变量,在整个程序的任何一个地方更改m的值,m的值都将改变,因此a()函数改变m的值后,main()函数中的m的值也发生了相应的改变。所以 ,调用a(3)后,在main()函数中输出cout<<m<<" "<<n<<endl; 结果为: 5 3
#include <iostream>
using namespace std;
class PP {
int x, y;
public:
PP() {
x = 3;
y = 5;
}
PP(int i, int j) {
x = i - y - j;
}
void Messages() {
cout << "x=" << x << " y=" << y << endl;
}
};
int main() {
PP* p1 = new PP();
PP p2(3, 4);
p2.Messages();
p1->Messages();
delete p1; // 释放动态分配的内存
return 0;
}
这段代码的分析过程如下:
- 包含了iostream头文件以使用输入输出流。
- 使用了
using namespace std
来避免每次都需要写std::
前缀。 - 声明了一个名为PP的类。
- 在PP类中,定义了私有成员变量x和y。
- 提供了两个构造函数:一个无参构造函数,用于初始化x和y的值为3和5;一个有参构造函数,用于将传入的参数分别赋值给x和y。
- 定义了一个名为Messages的成员函数,用来输出x和y的值。
- 定义了主函数main。
- 在主函数中,通过使用new关键字动态地创建了一个PP类的对象p1,并调用了其无参构造函数。这里使用了指针p1来存储对象的地址。
- 创建了一个PP类的对象p2,并调用了其有参构造函数,传入参数3和4。对象p2会在栈上分配内存。
- 调用p2的Messages函数,输出x和y的值,即输出"x=3 y=4"。
- 通过指针p1调用Messages函数,输出x和y的值,即输出"x=3 y=5"。
- 使用delete关键字释放动态分配的内存,即释放p1指向的对象的内存。
- 返回0,表示程序正常结束。最终输出结果为:
x=3 y=4
x=3 y=5
该代码主要展示了类的定义与使用。其中,类PP包含了两个构造函数、两个私有成员变量和一个成员函数。在主函数中,通过对象和指针分别创建并使用了PP类的实例。通过调用成员函数Messages,可以输出对象的成员变量x和y的值。最后,通过delete关键字释放了通过new关键字动态分配的内存,以避免内存泄漏。
分析一下过程#include <iostream>
using namespace std;
class A {
int a;
public:
A(int aa = 0) : a(aa) {
cout << a << " ";
}
~A() {
cout << "析构";
}
};
int main() {
A x[2] = {2};
cout << endl;
return 0;
}
这段代码的分析过程如下:
- 包含了iostream头文件以使用输入输出流。
- 使用了
using namespace std
来避免每次都需要写std::
前缀。 - 声明了一个名为A的类。
- 在A类中,定义了一个私有成员变量a。
- 提供了一个构造函数A,其中使用了参数的默认值0,用于初始化a的值。构造函数会输出a的值。
- 定义了一个析构函数~A,用于在对象被销毁时输出一条提示信息。
- 定义了主函数main。
- 在主函数中,创建了一个名为x的A类对象数组,数组大小为2。数组中的第一个对象会调用构造函数,并将参数2传入进行初始化。构造函数会输出2。数组中的第二个对象会使用参数的默认值0进行初始化。构造函数会输出0。
- 在主函数中,输出一个空行。
- 返回0,表示程序正常结束。最终输出结果为:
2 0 析构析构
代码的执行过程如下:
- 主函数开始执行。
- 创建一个名为x的A类对象数组,数组大小为2。
- 数组中的第一个对象会调用构造函数A(2),因此构造函数会输出2。
- 数组中的第二个对象会使用参数的默认值0进行初始化,因此构造函数会输出0。
- 在主函数中,输出一个空行。
- 主函数执行完毕,对象数组x会被销毁,先销毁第二个对象(析构函数输出"析构"),再销毁第一个对象(析构函数输出"析构")。因此,最终的输出结果是"2 0 析构析构"。(** 析构析构中间没有空!!!**)
#include <iostream>
using namespace std;
class A {
int a, b;
public:
A() {
a = 0;
b = 0;
}
A(int m) {
a = m;
b = 0;
}
A(int m, int n) {
a = m;
b = n;
}
void print() {
cout << "a=" << a << " b=" << b << endl;
}
};
int main() {
A a, a2(5), a3(5, 15);
a.print();
a2.print();
a3.print();
return 0;
}
修正后的代码的运行结果为:
a=0 b=0
a=5 b=0
a=5 b=15
代码的执行过程如下:
- 包含了iostream头文件以使用输入输出流。
- 使用了
using namespace std
来避免每次都需要写std::
前缀。 - 声明了一个名为A的类。
- 在A类中,定义了两个私有成员变量a和b。
- 提供了三个构造函数:
- 默认构造函数A(),将a和b都初始化为0。
- 构造函数A(int m),将a初始化为m,b初始化为0。
- 构造函数A(int m, int n),将a初始化为m,b初始化为n。
- 定义了一个成员函数print(),用于输出a和b的值。
- 定义了主函数main。
- 在主函数中,分别创建了三个A类对象a、a2和a3,分别使用了不同的构造函数进行初始化。
- 依次调用a、a2和a3的print()函数,分别输出a和b的值。
- 返回0,表示程序正常结束。因此,最终的运行结果为:
a=0 b=0
a=5 b=0
a=5 b=15
#include <iostream>
using namespace std;
class A {
public:
A() {
cout << "generate class A" << endl;
}
~A() {
cout << "destroy class A" << endl;
}
};
class B : public A {
public:
B() {
cout << "generate class B" << endl;
}
~B() {
cout << "destroy class B" << endl;
}
};
int main() {
B b;
return 0;
}
这段代码定义了两个类A和B,并在主函数中创建了一个B类对象b。类A和类B都定义了构造函数和析构函数,并且类B继承自类A。在程序执行过程中,首先创建了一个B类对象b。由于B类是A类的子类,因此在创建B类对象时,会先调用A类的构造函数,然后再调用B类的构造函数。因此,首先输出"generate class A",然后输出"generate class B"。 当程序执行完毕时,会先销毁B类对象b,调用B类的析构函数,输出"destroy class B",然后调用A类的析构函数,输出"destroy class A"。 因此,最终的运行结果为:
generate class A
generate class B
destroy class B
destroy class A
#include <iostream>
using namespace std;
class Base {
int x;
public:
virtual void Set(int b) {
x = b;
cout << "x=" << x << endl;
}
};
class Derived : public Base {
protected:
int y;
public:
void Set(int d) {
y = d;
cout << "y=" << y << endl;
}
};
int main() {
Base Bobj;
Derived Dobj;
Base* p;
p = &Bobj;
p->Set(100);
p = &Dobj;
p->Set(200);
return 0;
}
这段代码定义了两个类Base和Derived,并在主函数中创建了一个Base类对象Bobj和一个Derived类对象Dobj。类Base和类Derived都定义了函数Set,并且类Derived继承自类Base。在程序执行过程中,首先创建了一个Base类对象Bobj和一个Derived类对象Dobj。 接下来,声明了一个Base指针变量p,并将p指向Bobj。然后通过p调用Set(100)函数,由于Set函数是虚函数,所以会根据指针指向的对象类型调用相应的函数。这里p指向的是Base类对象Bobj,所以调用了Base类的Set函数,输出"x=100"。 然后,将p指向Dobj。再次通过p调用Set(200)函数,同样根据指针指向的对象类型调用相应的函数。这里p指向的是Derived类对象Dobj,所以调用了Derived类的Set函数,输出"y=200"。 因此,最终的运行结果为:
x=100
y=200