1.总体目录
2.左值和右值
左值:可以进行取地址
右值:不能进行取地址,临时对象、匿名对象、临时变量、字面值常量(100)都属于右值
3.具体细节
类和对象的具体讲解
一、简答题
1.设A为test类的对象且赋有初值,则语句test B(A); 表示。
调用了拷贝构造函数,以A为原型构造了新的test类对象B
2.利用“对象名.成员变量”形式访问的对象成员仅限于被声明为 (1)的成员;若要访问其他成员变量,需要通过 (2) 函数
(1):public
(2):成员
3.浅拷贝与深拷贝区别?
类型 | 浅拷贝 | 深拷贝 |
---|---|---|
区别 | ①只拷贝指针地址 ②当两个对象指向同一个空间的数据,一个对象被销毁时,另一个对象就获取不到相应的数据了 |
①拷贝指针不指向同一块数据空间,而是指向空间内容 ②两个对象都有独立的数据,一个对象销毁不会影响到另外一个对象 |
二、写出下面程序结果。
1、写出以下程序运行的结果。( )
#include
using std::cout;
using std::endl;
class Sample
{
public:
Sample();//创建对象先执行构造函数一次
void Display();
private:
int i;
static int k;//由于是static,会按对象的数量依次增加
};
Sample::Sample()
{
i=0;
k++;
}
void Sample::Display()
{
cout << "i=" << i << ",k=" << k << endl;
}
int Sample::k=0;
int main( )
{
Sample a, b;
a.Display();//a和b是独立计算的
b.Display();
return 0;
}
//运行结果是:
//i=0 ,k=2
//i=0, k=2
2、设有如下程序结构:
class Box
{
//....
};
int main()
{
Box A,B,C;
}
该程序运行时调用_3_次构造函数;调用_3_次析构函数。
3、写出下面程序的运行结果()
#include
using std::cout;
using std::endl;
class Sample
{
int i;
public:
Sample();
Sample(int val);
void Display();
~Sample();
};
Sample::Sample()
{
cout << "Constructor1" << endl;
i=0;
}
Sample::Sample(int val)
{
cout << "Constructor2" << endl;
i=val;
}
void Sample::Display()
{
cout << "i=" << i << endl;
}
Sample::~Sample()
{
cout << "Destructor" << endl;
}
int main()
{
Sample a, b(10);//先各自执行一次对应的构造函数
a.Display();//后各自打印对象里面的i值
b.Display();
return 0;
}
//输出结果如下:
//Constructor1
//Constructor2
//i=0
//i=10
//Destructor
//Destructor
4、设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为?
C c;
void main()
{
A *pa=new A();
B b;
static D d;//静态函数和全局变量是相当于一起的,但是全局变量先入栈
delete pa;//先手动析构函数delete释放A
}
//A B D C
5、写出下面程序的结果:
#include
using std::cout;
using std::endl;
int i = 1;
class Test
{
public:
Test()
:_fourth(_third)
,_second(i++)
,_first(i++)
,_third(i++)
{
_third = i;
}
void print()
{
cout << "result : " << _first + _second + _third + _fourth << endl;
}
private:
int _first;//先给_first赋值为1,i自增为2
int _second;//后给_second赋值i的值为2,i自增为3
int _third;//然后给_third赋值i的值为3,i自增为4
int &_fourth;//_fourth引用_third为3,由于_third=i,i为4,也就是_fourth为4
};
int main()
{
Test test;
test.print();
return 0;
}
//输出结果为
//result : 11
6、下列代码在编译时会产生错误的是()
#include
using std::cout;
using std::endl;
struct Foo
{
Foo()
{
}
Foo(int)
{
}
void func()
{
}
};
int main(void)
{
Foo a(10);//语句1
a.func();//语句2
Foo b();//语句3 ,默认声明了返回类型为Foo的b函数
b.func();//语句4 语句四报错
return 0;
}
三、改错题。
例题1:分析找出以下程序中的错误,说明错误原因,给出修改方案使之能正确运行。
#include
using std::cout;
using std::endl;
class Base
{
int a1,a2;
public:
Base(int x1 = 0, x2 = 0);
};
int main()
{
Base data(2,3);
cout << data.a1 << endl;//data.a1不是类型名或调用了成员函数
cout << data.a2 << endl;
return 0;
}
修正为
#include
using std::cout;
using std::endl;
class Base
{
//int a1,a2;
public:
Base( int a1=0 , int a2 = 0){
_a1=a1;
_a2=a2;
}
int ret_a1(){//增加
return _a1;
}
int ret_a2(){//增加
return _a2;
}
private://全局变量修改为private变量
int _a1;
int _a2;
};
int main()
{
Base data(2,3);
cout << data.ret_a1() << endl;
cout << data.ret_a2() << endl;
return 0;
}
#include
using std::cout;
using std::endl;
class Base
{
//int a1,a2;
public:
Base( int a1=0 , int a2 = 0)
:_a1(a1),
_a2(a2){
}
int ret_a1(){
return _a1;
}
int ret_a2(){
return _a2;
}
private:
int _a1;
int _a2;
};
int main()
{
Base data(2,3);
cout << data.ret_a1() << endl;//返回
cout << data.ret_a2() << endl;
return 0;
}
例题2:分析以下程序的错误原因,给出修改方案使之能正确运行。
#include
using std::cout;
using std::endl;
class Base
{
float _ix;
float _iy;
public:
Base(float ix,float iy)
{
_ix = ix;
_iy = iy;
}
float gain();
};
Base::float gain()
{
return _iy/_ix;
}
int main()
{
Base base(5.0,10.0);
cout << "The gain is => " << gain() << endl;
return 0;
}
#include
using std::cout;
using std::endl;
class Base
{
float _ix;
float _iy;
public:
Base(float ix,float iy)
{
_ix = ix;
_iy = iy;
}
float gain();
};
float Base::gain()
{
return _iy/_ix;
}
int main()
{
Base base(5.0,10.0);
cout << "The gain is => " << base.gain() << endl;
return 0;
}
四、编程题。
1、定义一个学生类,其中有3个数据成员:学号、姓名、年龄,以及若干成员函数。同时编写main函数使用这个类,实现对学生数据的赋值和输出。
#include
#include
using namespace std;
class Student
{
private:
/* data */
int _num;//学号
char _name[20];//姓名
int _age;//年龄
public:
Student(int num,const char name[],int age)
: _num(num),
_age(age)
{
strcpy(_name,name);
}
void print_data(){
std::cout<< "学号 :"<<_num;
std::cout<< "姓名 :"<<_name;
std::cout<< "年龄 :"<<_age<<std::endl;
}
//~num4_1();
};
// num4_1::num4_1(/* args */)
// {
// }
// num4_1::~num4_1()
// {
// }
int main()
{
std::cout << "Hello world" << std::endl;
Student xiaoming(1,"xiaoming",20);
xiaoming.print_data();
Student xiaohu(2,"xiaohu",21);
xiaohu.print_data();
return 0;
}
2、编写一个程序计算两个给定的长方形的周长和面积。
#include
using namespace std;
class Tiangle
{
private:
/* data */
int _length;
int _wideth;
public:
Tiangle(int length=0,int wideth=0)
: _length(length),
_wideth(wideth)
{
}
int printf_length(){
std::cout<<"长方体周长="<< 2*(_length+_wideth) <<std::endl;
return 2*(_length+_wideth);
}
int printf_size(){
std::cout<<"长方体面积="<< (_length*_wideth) <<std::endl;
return (_length*_wideth);
}
//~num4_2();
};
// Tiangle::Tiangle(/* args */)
// {
// }
// num4_2::~num4_2()
// {
// }
int main()
{
Tiangle xiaosi(2,6);
std::cout<< xiaosi.printf_length() << std::endl;
std::cout<< xiaosi.printf_size() << std::endl;
return 0;
}
3、编写一个类,实现简单的栈。栈中有以下操作:
> 元素入栈 void push(int);
> 元素出栈 void pop();
> 读出栈顶元素 int top();
> 判断栈空 bool emty();
> 判断栈满 bool full();
如果栈溢出,程序终止。栈的数据成员由存放10个整型数据的数组构成。(可以自己设计入栈出栈的数据)
提示:就是用C++类的方式实现一个栈,然后写出栈的基本操作,入栈、出栈、栈为空、栈为满的函数,以及模拟栈的入栈出栈的操作。
#ifndef __Stackklx_H__
#define __Stackklx_H__
#include
using namespace std;
template<class T>
class Stackklx{
private:
T *arr;
int count;
public:
Stackklx();//构造函数
~Stackklx();//析构函数
T top();
T pop();
void push(T t);
int size();//存储了栈元素的数量
bool isEmpty();//判断是否为空
bool full();//判断栈满
};
//构造函数创建栈
template<class T>
Stackklx<T>::Stackklx(){
arr=new T(10);
if(!arr){
std::cout<< "初始化new失败!" <<std::endl;
}
}
//析构函数销毁栈
template<class T>
Stackklx<T>::~Stackklx(){
if(arr){
delete [] arr;
arr=NULL;
}
}
//数据压栈
template<class T>
void Stackklx<T>::push(T t){
arr[count++]=t;
std::cout<< "数据"<< t << "已经压栈!"<<std::endl;
}
//返回栈顶元素
template<class T>
T Stackklx<T>::top(){
return arr[count-1];
}
//弹栈
template<class T>
T Stackklx<T>::pop(){
int ret=arr[count-1];
count--;
std::cout<< "数据"<< ret << "已经弹栈!"<<std::endl;
return ret;
}
//返回栈的大小
template<class T>
int Stackklx<T>::size(){
return count;
}
//判断栈是否为空
template<class T>
bool Stackklx<T>::isEmpty(){
if(size()==0){
return true;
}else{
return false;
}
}
//判断栈是否为满
template<class T>
bool Stackklx<T>::full(){
if(size()==10){
return true;
}else{
return false;
}
}
#endif
int main()
{
int tmp=0;
Stackklx<int>*Stack=new Stackklx<int>();//new一个class为Stackklx的类
Stack->push(10);//压栈10
Stack->push(15);//压栈15
Stack->push(23);//压栈23
Stack->push(25);//压栈25
tmp=Stack->top();
std::cout<< "栈顶元素为: " <<tmp<<std::endl;
std::cout<<std::endl;
std::cout<<"现在循环输出栈内元素:"<<std::endl;
while (!Stack->isEmpty())
{
tmp=Stack->pop();
//std::cout<
}
std::cout<<std::endl;
return 0;
}
4、编写一个类,实现简单的队列。队列中有以下操作:
> 元素入队 void push(int);
> 元素出队 void pop();
> 读取队头元素 int front();
> 读取队尾元素 int back();
> 判断队列是否为空 bool emty();
> 判断队列是否已满 bool full();
注意循环队列的使用
提示:就是用C++类的方式实现一个队列,然后写出队列的基本操作,入队列、出队列、队列为空、队列为满的函数,以及模拟队列的入队列出队列的操作。
//思路:两个栈,一个专门入栈,一个专门出栈
#ifndef __Stackklx_H__
#define __Stackklx_H__
#include
using namespace std;
template<class T>
class Stackklx{
private:
T *arr;
int count;
public:
Stackklx();//构造函数
~Stackklx();//析构函数
T front();
T pop();
T back();
int push(T t);
int size();//存储了栈元素的数量
bool isEmpty();//判断是否为空
bool full();//判断栈满
};
//构造函数创建栈
template<class T>
Stackklx<T>::Stackklx(){
arr=new T(10);
if(!arr){
std::cout<< "初始化new失败!" <<std::endl;
}
}
//析构函数销毁栈
template<class T>
Stackklx<T>::~Stackklx(){
if(arr){
delete [] arr;
arr=NULL;
}
}
//数据压栈
template<class T>
int Stackklx<T>::push(T t){
arr[count++]=t;
//std::cout<< "数据"<< t << "已经压栈!"<
return arr[count-1];
}
//弹栈
template<class T>
T Stackklx<T>::pop(){
int ret=arr[count-1];
count--;
//std::cout<< "数据"<< ret << "已经出队!"<
return ret;
}
//读取队头元素
template<class T>
T Stackklx<T>::front(){
int ret=arr[0];
std::cout<< "队头元素为"<< ret <<std::endl;
return ret;
}
//读取队尾元素
template<class T>
T Stackklx<T>::back(){
int ret1=size();
int ret=arr[0];
std::cout<< "队尾元素为"<< ret <<std::endl;
return ret;
}
//返回栈的大小
template<class T>
int Stackklx<T>::size(){
return count;
}
//判断栈是否为空
template<class T>
bool Stackklx<T>::isEmpty(){
if(size()==0){
return true;
}else{
return false;
}
}
//判断栈是否为满
template<class T>
bool Stackklx<T>::full(){
if(size()==10){
return true;
}else{
return false;
}
}
#endif
int main()
{
int tmp=0;
Stackklx<int>*Stack1=new Stackklx<int>();//new一个class为Stackklx的类,对象名为Stack1
Stackklx<int>*Stack2=new Stackklx<int>();//new一个class为Stackklx的类,对象名为Stack2
tmp=Stack1->push(10);//压栈10
std::cout<< "数据"<< tmp << "已经入队!"<<std::endl;
tmp=Stack1->push(15);//压栈15
std::cout<< "数据"<< tmp << "已经入队!"<<std::endl;
tmp=Stack1->push(23);//压栈23
std::cout<< "数据"<< tmp << "已经入队!"<<std::endl;
tmp=Stack1->push(25);//压栈25
std::cout<< "数据"<< tmp << "已经入队!"<<std::endl;
tmp=Stack1->front();
std::cout<< "输出队头元素"<< tmp <<std::endl;
std::cout<<std::endl;
//栈1输出到栈2
while(!Stack1->isEmpty()){
tmp=Stack1->pop();
Stack2->push(tmp);
}
tmp=Stack2->back();
std::cout<< "输出队尾元素"<< tmp <<std::endl;
std::cout<<std::endl;
std::cout<<"现在循环输出队内元素:"<<std::endl;
while (!Stack2->isEmpty())
{
tmp=Stack2->pop();
std::cout<< "输出队尾元素"<< tmp <<std::endl;
}
std::cout<<std::endl;
return 0;
}
mp=Stack1->push(15);//压栈15
std::cout<< "数据"<< tmp << "已经入队!"<<std::endl;
tmp=Stack1->push(23);//压栈23
std::cout<< "数据"<< tmp << "已经入队!"<<std::endl;
tmp=Stack1->push(25);//压栈25
std::cout<< "数据"<< tmp << "已经入队!"<<std::endl;
tmp=Stack1->front();
std::cout<< "输出队头元素"<< tmp <<std::endl;
std::cout<<std::endl;
//栈1输出到栈2
while(!Stack1->isEmpty()){
tmp=Stack1->pop();
Stack2->push(tmp);
}
tmp=Stack2->back();
std::cout<< "输出队尾元素"<< tmp <<std::endl;
std::cout<<std::endl;
std::cout<<"现在循环输出队内元素:"<<std::endl;
while (!Stack2->isEmpty())
{
tmp=Stack2->pop();
std::cout<< "输出队尾元素"<< tmp <<std::endl;
}
std::cout<<std::endl;
return 0;
}