注:适合至少学了一学期的c++人士浏览,今天复习了一晚上的c++,只是写了冰山一角,如果有理解错误的地方,欢迎指出,谢谢。
杂识(掌握的知识文字化):
a.类和对象的关系可表述为:类是对象的抽象,而对象则是类的实例。
b.静态成员函数没有隐含的 this指针 ,所以在c++程序中,静态成员函数主要用来访问静态数据成员,而不访问非静态成员。
c.c++中的两种代码复用方式:继承 和 组合或模板。
d.析构函数的作用是 在对象被系统释放之前做一些内存处理工作。
1.类中的this指针
关于this指针的一个精典回答:
当你进入一个房子后,你可以看见桌子、椅子、地板等,但是房子你是看不到全貌了。
对于一个类的实例来说,你可以看到它的成员函数、成员变量,但是实例本身呢?this是一个指针,它时时刻刻指向你这个实例本身。
注:this指针不能用于构造函数的初始化链表。
class Square : public Shape{
double a;
public:
Square(double a) : this->a(a){}//error
Square(double a) { this->a = a;}
};
友元破坏了c++封装性,带来了便捷的访问,减少了函数间传递的参数,也不知道是好是坏。
我对友元的理解,如果一个类里面声明了友元函数或者友元类,你可以把这个类先想成是你的屋子,然后那个友元函数或者友元类就是主人的朋友,但是这个朋友很自私,你愿意让他参观你的卧室和厕所等(类比private数据),但是他不会让你参观他的屋子。如下,B的对象可以访问A对象中的a,A的对象不能访问B中对象的b。
class B;
class A
{
private:
<span style="white-space:pre"> </span>int a;
<span style="white-space:pre"> </span>friend class B;//B可访问A,A不能访问B,除非在B中也声明friend class A.
};
class B
{
private:
<span style="white-space:pre"> </span>int b;
};
因此下面这几条表述可以轻松的找出错误的一条。
a.友元函数可以访问该类的私有数据成员。
b.一个类的友元类中的成员函数都是这个类的友元函数。
c.友元可以提高程序的运行效率。
d.类与类之间的友元关系可以继承。//朋友的朋友不一定是朋友
3.继承与派生
基类成员在派生类中的访问属性:
基类中的成员 在公用派生类中的访问属性在私有派生类中的访问属性 在保护派生类中的访问属性
私有成员 不可访问 不可访问 不可访问//这样看着好看一点
公有成员 公用 私有 保护
保护成员 保护 私有 保护
4.多态性
多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphisn),字面意思多种形状。
多态性从实现的角度可以划分为两类:静态多态性和动态多态性。
函数的重载能实现静态多态性。
虚函数实现动态多态性。
函数的重载没什么好说的。
虚函数实现多态性重要是理解固定偏移量这个东西,我对固定偏移量的理解是这样的:
固定偏移量改变可以使一个指针的地址改变,从而指向派生类中的实现函数。如果你的类中函数前没有virtual关键字,那么他的固定偏移量就不可变,否则可变,这是实现多态的关键。如:
#include<iostream>
using namespace std;
class A
{
public:
void foo()
{
cout<<"1 ";
}
virtual void fun()
{
cout<<"2 ";
}
};
class B : public A
{
public:
void foo()
{
cout<<"3 ";
}
void fun()
{
cout<<"4 ";
}
};
int main()
{
A a;
B b;
A *p = &a;
p->foo();
p->fun();
p = &b;
p->foo();
p->fun();
return 0;
}
输出的结果是1 2 1 4。我们注意到只有类A中有一个虚函数
virtual void A::fun()
{
cout<<"2 ";
}
观察main函数,首先很简单是一个基类指针(class A)p指向一个基类对象(a),
调用的都是基类本身的函数,因此输出结果就是1、2。第二次基类指针p指向派生类B,先调用
的是void foo()函数,由于A中的foo()函数并没有加virtual虚化,所以他的固定偏移量不可变,即还是调用基类A中的foo()函数,输出1 ,而再调用fun()函数,有virtual虚化,可以改变固定偏移量达到指向派生类B中fun()函数的目的,故输出4 。笔试的题目中还有一个另类测试方法。即
B *ptr = (B *)&a; ptr->foo(); ptr->fun();
问这两调用的输出结果。这是一个用子类的指针去指向一个强制转换为子类地址的基类对象。结果,这两句调用的输出结果是3,2。
5.const