1.问题
1.1C和C++的区别???
1.c是面向过程的语言,c++是面向对象的语言,
2.结构体变量:在c++中支持结构体定义成员函数,C语言中不支持,会报错,
3.输入输出不同
C语言中用scanf()和printf()
c++中用cin和cout
4.动态内存分配:
c++ 用new delete
c用malloc free
5.其他区别
常量的表示方法不一样
C语言中不支持引用的概念 ,而c++支持
注释不同,c89不支持单行注释,
1.2你怎么理解面向对象OOP?你怎么用OOP思想来解决问题?
OOP具有三大特点:
1.封装性:也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法。于是开发人员只需要关注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现MVC分工合作,也能有效避免程序间相互依赖,实现代码模块间松藕合。
2.继承性:就是子类自动继承其父级类中的属性和方法,并可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。php只支持单继承,也就是说一个子类只能有一个父类。
3.多态性:子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。于是多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,这种技术就是多态性。多态性增强了软件的灵活性。
1.3面向对象语言的四大特征是什么?三大特征?
抽象
封装/隐藏
继承
多态
1.4struct和class都都够定义类类型
区别1:成员默认的访问限定不一样
《剑指offer》
struct Data{}; C和C++里面定义这么一个空结构体,sizeof(Data)的结果是否一样
main.c main.cpp
vs gcc
struct Data1
{
char ch1;
char ch2;
char ch3;
};
sizeof(Data1);
结构体 =》 变量 分配内存
类 =》 对象 分配内存 对象构造CGoods(CGoods *this)
1.5类
2.类通过访问限定符(public private protected),来体现OOP的封装隐藏思想
3.成员方法的定义有两个地方:类里面直接定义 在类外定义
4.计算对象内存占用大小的时候,只计算对象的成员变量,不包括对象的成员方法
一个类型定义的很多对象,它们都有自己的一份成员变量,但是他们共享成员方法
CGoods good1; CGoods good2;
1.6this指针 什么是this指针?
内在:所有对象共享一套成员方法,用来区分是哪个对象调用成员方法的。
对象调用成员方法的时候,编译器编程成,调用方法时,把对象的地址当作实参传递进去;
那么所有成员方法在编译时期就会自动添加一个形参,就是this指针,在成员方法中,用 来区分不同的对象。 谁调用方法,this指针就指向谁。
1.7指针和引用的区别?
引用在底层也是表现为一个指针
指针不需要初始化,而引用一定得初始化
指针有多级指针,引用没有多级引用(C++11 右值引用)
2.OOP来描述一个栈结构
const int STACK_SIZE = 20;
class CSeqStack
{
public:
// 构造函数可以重载 专门做对象成员初始化操作
// 默认构造 CSeqStack s1;
/*CSeqStack()
{
mTop = 0;
mSize = 10;
mpStack = new int[mSize];
cout << "CSeqStack()" << endl;
}*/
// 带参数的构造函数 CSeqStack s1; CSeqStack s2(20);
CSeqStack(int size=10)
{
cout << this << endl;
mTop = 0;
mSize = size;
mpStack = new int[mSize];
cout << "CSeqStack(int)" << endl;
}
//CSeqStack stack3 = stack1;
//拷贝构造函数
//memcpy realloc
CSeqStack(const CSeqStack &src)
{
cout << &src << "=>" << this << endl;
//mpStack = src.mpStack;
mpStack = new int[src.mSize];
for (int i = 0; i < src.mTop; ++i)
{
mpStack[i] = src.mpStack[i];
}
mTop = src.mTop;
mSize = src.mSize;
}
// 析构函数只能有一个 专门做资源释放操作
~CSeqStack()
{
cout << this << endl;
delete[]mpStack;
mpStack = NULL;
cout << "~CSeqStack()" << endl;
}
void init(int size=10); // 栈的初始化
void release(); // 资源释放的函数
void push(int data) // 入栈操作
{
if (full())
{
// 2被的扩容 realloc
int *ptmp = new int[mSize*2];
// memcpy(ptmp, mpStack, sizeof(int)*mSize);
for (int i = 0; i < mSize; ++i)
{
ptmp[i] = mpStack[i];
}
delete []mpStack;
mpStack = ptmp;
mSize *= 2;
}
mpStack[mTop++] = data;
}
void pop() // 出栈操作
{
if (empty())
return;
--mTop;
}
int top() // 获取栈顶元素
{
if (empty())
throw "栈空了"; // 抛出异常结束函数运行就可以了
return mpStack[mTop-1];
}
bool full() // 栈满
{
return mTop == mSize;
}
bool empty() // 栈空
{
return mTop == 0;
}
private:
int *mpStack;
int mTop;
int mSize;
};
void CSeqStack::init(int size)
{
mTop = 0;
mSize = size;
//(int*)malloc(sizeof(int)*size);
mpStack = new int[size];
}
void CSeqStack::release()
{
delete []mpStack;
}
int main()
{
// CSeqStack stack1(15);
// CSeqStack stack2;
CSeqStack stack1(15); // 对象资源的初始化和最终的释放能够自动进行调用处理
}
3.用OOP实现下面的内存可增长的循环队列
class CircleQueue
{
public:
CircleQueue(int size = 10)
{
mSize = size;
mFront = mRear = 0;
mpQue = new int[mSize];
/*
new malloc delete free
malloc和free是属于函数
new和delete是运算符
malloc只能开辟空间
newxxxxxx,xxxxxx
*/
}
CircleQueue(const CircleQueue &src)
{
mSize = src.mSize;
mFront = src.mFront;
mRear = src.mRear;
mpQue = new int[mSize];
for (int i = mFront; i < mRear; i = (i + 1) % mSize)
{
mpQue[i] = src.mpQue[i];
}
}
void operator=(const CircleQueue &src)
{
cout << "operator=" << endl;
// 先排除自赋值
if (this == &src)
return;
// 先释放当前对象原来占用的外部资源
delete[]mpQue;
// 重新给当前对象分配外部资源空间并进行数据拷贝
mSize = src.mSize;
mFront = src.mFront;
mRear = src.mRear;
mpQue = new int[mSize];
for (int i = mFront; i < mRear; i = (i + 1) % mSize)
{
mpQue[i] = src.mpQue[i];
}
}
~CircleQueue()
{
delete []mpQue;
mpQue = NULL;
}
void addQue(int data)
{
if (full())
{
int *pTmp = new int[2 * mSize];
for (int i = mFront, j=0;
i < mRear;
i = (i + 1) % mSize,j++)
{
pTmp[j] = mpQue[i];
}
mFront = 0;
mRear = mSize;
mSize *= 2;
delete []mpQue;
mpQue = pTmp;
}
mpQue[mRear] = data;
mRear = (mRear + 1) % mSize;
}
void delQue()
{
if (empty())
return;
mFront = (mFront + 1) % mSize;
}
int front()
{
if (empty())
throw "queue is empty!";
return mpQue[mFront];
}
int back()
{
if (empty())
throw "queue is empty!";
return mpQue[(mRear + mSize - 1) % mSize];
}
bool full(){ return (mRear + 1) % mSize == mFront; }
bool empty(){ return mRear == mFront; }
private:
int *mpQue;
int mFront;
int mRear;
int mSize;
// 把拷贝构造函数生命私有化,这样外部就不能够进行调用了
// CircleQueue(const CircleQueue &);
// int sum(int a, int b){return a+b;} sum(10, 20);
};
int main4()
{
CircleQueue queue1;
CircleQueue queue2 = queue1;
/*
C++中,所有对象的运算都被转换成,成员方法的调用,左边对象调用相应
成员方法,把右边的对象当作实参传递进去
queue2 = queue1
void operator=(const CircleQueue &src)
queue2.operator=(queue1)
queue2 > queue1
queue.operator>(queue1)
*/
queue1 = queue1;
return 0;
}
4.oop实现string
class String
{
public:
String(const char *str = NULL) // String str1;
{
if (str != NULL)
{
//try
//{
m_data = new char[strlen(str) + 1];
//}
//catch (const bad_alloc &err)
//{
//}
// new内存开辟失败,不返回NULL指针,而是抛出bad_alloc类型的异常
strcpy(m_data, str);
}
else
{
m_data = new char[1];
*m_data = '\0';
}
}
~String()
{
delete []m_data;
m_data = NULL;
}
String(const String &other)
{
m_data = new char[strlen(other.m_data) + 1];
strcpy(m_data, other.m_data);
}
String& operator=(const String &other)
{
if (this == &other)
return *this;
delete[]m_data;
m_data = new char[strlen(other.m_data) + 1];
strcpy(m_data, other.m_data);
return *this;
}
private:
char *m_data;
};
class CString
{
public:
CString(char *p = NULL);
~CString();
CString(const CString &src);
CString& operator=(const CString &src);
bool operator>(const CString &src)const;
bool operator<(const CString &src)const;
bool operator==(const CString &src)const;
int length()const;
char operator[](int index)const;
const char* c_str()const;
private:
char *_pstr;
};
CString operator+(const CString &lhs, const CString &rhs);
ostream& operator<<(ostream &out, const CString &str);
int main()
{
CString str1 = "aaa";
CString str2 = str1;
CString str3;
str3 = str1;
CString str4 = str1 + str3;
str4 = str1 + "bbb";
str4 = "ccc" + str1;
cout << str4 << endl;
if (str4 > str1)
{
cout << "str4 > str1" << endl;
}
else
{
cout << "str4 < str1" << endl;
}
int len = str4.length();
for (int i = 0; i < len; i++)
{
//char str4.operator[](int index)
cout << str4[i]<<" ";
}
cout << endl;
// string char[]
char buf[1024] = { 0 };
strcpy(buf, str4.c_str());
cout << "buf:" << buf << endl;
string str5 = "hello world";
// 按迭代器遍历的方式
string::iterator it = str5.begin();
for (; it != str5.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
5.用OOP实现链表操作
struct Node
{
Node(int data=0)
{
mdata = data;
mpnext = NULL;
}
int mdata;
Node *mpnext;
};
class CLink
{
public:
CLink()
{
mphead = new Node();
}
~CLink()
{
Node *pcur = mphead;
while (pcur != NULL)
{
mphead = mphead->mpnext;
delete pcur;
pcur = mphead;
}
}
CLink(const CLink &src)
{
mphead = new Node();
Node *plast = mphead;
Node *pcur = src.mphead->mpnext;
while (pcur != NULL)
{
Node *pnew = new Node(pcur->mdata);
plast->mpnext = pnew;
plast = pnew;
pcur = pcur->mpnext;
}
}
CLink& operator=(const CLink &src)
{
if (this == &src)
return *this;
Node *psrc = src.mphead->mpnext;
Node *pcur = mphead->mpnext;
while (psrc != NULL
&& pcur != NULL)
{
pcur->mdata = psrc->mdata;
pcur = pcur->mpnext;
psrc = psrc->mpnext;
if (ppre->mpnext == NULL)
{
ppre->mpnext = new Node(psrc->mdata);
}
else
{
ppre->mpnext->mdata = psrc->mdata;
}
ppre = ppre->mpnext;
psrc = psrc->mpnext;
}
if (psrc != NULL)
{
// 删除ppre后面的所有节点
}
else // pcur != NULL 不要写两个并列的if语句
{
}
}
void insertHead(int data)
{
Node *pcur = new Node(data);
pcur->mpnext = mphead->mpnext;
mphead->mpnext = pcur;
}
void insertTail(int data)
{
Node *pcur = mphead;
while (pcur->mpnext != NULL)
{
pcur = pcur->mpnext;
}
pcur->mpnext = new Node(data);
}
void removeNode(int data)
{
Node *ppre = mphead;
Node *pcur = mphead->mpnext;
while (pcur != NULL)
{
if (pcur->mdata == data)
{
ppre->mpnext = pcur->mpnext;
delete pcur;
pcur = ppre->mpnext;
}
else
{
ppre = pcur;
pcur = pcur->mpnext;
}
}
}
void show()
{
Node *pcur = mphead->mpnext;
while (pcur != NULL)
{
cout << pcur->mdata << " ";
pcur = pcur->mpnext;
}
}
private:
Node *mphead;
};