其实就是一些面试前看的一些内容

CCompany(const CCompany& rhs);
~CCompany()
const CCompany& operator+=() const;
0
void Setattr(int a = 1,int b,int c = 0);
#define / const
strlen() / strcpy() / strcmp() / strcat() / #include <string.h>
// sizeof...stelen...

//25,26 

// argc...argv...

// const的位置

class MyClass{

friend MyClass& operator++(MycClass& rhs);
friend MyClass& operator--(MycClass& rhs);
public:
MyClass& operator++();
Myclass& operator--();
}




private / public / protected


private是最能体现封装特性的一个访问级别,通常情况下,对象无法访问到private修饰的成员变量或成员函数。而public是类的设计者提供的一种合理的外部访问接口,通过接口来执行某种操作。protected则是介于两者之间的,类的对象无法访问由protected修饰的成员变量或者成员函数,但是protected所在类的派生类是可以直接访问其修饰的对象的。


// 数据库


函数的值传递和引用传递。一般来说,内置类型我们还是采用值传递的好,自定义的类等还是采用引用传递。值传递的时候,形参会执行构造函数以及内部成员的定义/初始化,创造形参的副本,也就是函数内部的操作只会对副本进行操作,而不会对形参本身有什么影响。而引用传递直接传递的是参数本身,不会有构造成本,函数直接可以对参数进行修改。如果我们仅仅使用实参,而不需要对参数进行修改,只需要这么来传递参数。void function(const class& ...)




函数的重载:函数的形参或者形参个数不一致,主要是为了在执行大致相同任务的函数里边,找到一种适合使用和管理的方式。






// 分区排序


析构函数是对象在生命周期到了之后,调用的函数,用来释放申请的资源。
虚函数是实现多态的一种方式,直观的表现是基类中需要被覆盖的函数被Virtual关键字所修饰,从而当基类指针指向子类的对象时,可以调用到子类的函数。从而实现基类拥有了子类的特性。也是一种代码重用的方式。


全局变量和局部变量的声明的位置不同,局部变量一般申请在函数的内部,全局变量申请在类、函数之外。


// 网络结构和TCP/IP




struct和class在使用上大致相同,都可以使用private,public,protected等,但是不显式的表明变量的访问权限,struct默认的是Public,而class默认的是private


封装、继承、多态




“#”开头的指令,就是为编译工作做的预备工作的阶段,是在程序编译前就进行的预处理工作。c提供的功能主要有三种:宏定义、文件包含、条件编译。


条件编译:#if、#endif 
宏定义: #define
文件包含:#include




宏定义是在预编译的阶段对代码的简单替换,枚举敞亮是在编译阶段的时候确定值的


NULL的定义:
 
  #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif




// 递归


new和delete,malloc和free经常是成对出现的,都是在堆内存里边申请资源。new操作符会调用构造函数,delete会调用析构函数,而malloc和free不会。




类的构造函数不能被声明为虚函数,因为对象在构造的时候必须是明确的。std::string不能做为switch的参数类型。冒泡排序算法的时间复杂度O(N的平方),
堆栈溢出的原因是:忽略在堆栈内存中分配的内存大小,向申请的内存中写入了过多的数据导致数据越界。




float x;
if(x-0<0.000000001);


static:在函数中的某些变量的生命周期超过函数的声明周期,可以将函数的变量声明为static变量,用于存储历史的值。


变量仅仅在本文件和引用了本文件的头文件中使用


// 网络协议


全局变量和局部变量位置中的区别:全局变量可以申请在头文件的任意位置,局部变量仅仅申请在函数的内部。全局变量在文件中有效,而局部变量仅仅在函数的内部有效。


全局变量和局部变量内存中的区别: 一般来说,程序在申请内存的时候,会有4类不同的内存申请位置。堆、栈、数据域(全局变量和静态变量),代码域。局部变量在申请内存的时候,是在堆上申请或者栈上申请,而全密变量申请的位置是在全局区域。


引用只是变量的另一个名字,而指针只是存储变量的地址。不存在空引用,但是空指针是可以存在的。


// 约瑟夫环 (循环链表或者其他方式都可以解决)


// 逆序




char a[] = "abcd";
char* c = "abcd";


sizeof(a) = 5;
std::strlen(a) = 4;


sizeof(c) = 4;
std::strlen(c) = 4;


ifndef define endif 预处理程序,在程序编译前被处理,还有防止被重复编译的问题


#include <> 包含库文件
#include "" 在工程文件夹下寻找自己编写的头文件


C++属于强类型语言,我们在编写作用类似的函数或者类的时候,不得不去针对每一种类型都作设计,站在代码的重复利用利用的角度来看的话,肯定是比较冗余。模板的出现,屏蔽了数据类型的差异,写出相同的代码,减少代码的冗余。


模板是编译的时候确定数据的类型,保证数据安全。




// 线程、进程(Windows、Linux)


比较耗时的操作都可以使用线程,在后台作运算处理,提高软件的响应。




// 数据库(mysql)


数据库的日志满了之后,只能进行读操作。




// 内存对齐


exit()函数退出程序后,将程序的控制权交还给控制系统。而return只是将控制权交给调用该函数的函数。断点调试可以看见,在exit()下了断点之后,当函数执行了这一句,程序就会结束,不会再进入到调用该函数的函数。而return 则会进入到调用该函数的函数。


纯虚函数:不需要实现,子类必须实现该函数


虚函数:父类里需要实现,子类需要重写该函数,体现子类的差异化。


静态成员函数:被static修饰的成员函数,一般函数里没有对类的成员变量的修改。


成员函数:普通的函数接口


当基类的指针指向派生类的对象时候,需要将类的析构函数声明为虚函数。当对象的声明周期结束后,首先调用的是基类的析构函数,如果不加virtual,仅仅是将基类的内存资源所释放,而子类的并没有释放。




delete 和delete[] 其实是两个被重载的操作符号。


operator delete     operator delete[] 一个针对普通的变量,一个是针对数组






没有把运算符重载设置为类的成员函数是:加法满足的是交换律,如果设置为成员函数,将会仅仅是a+b而不能实现b+a。




不能,传递的是参数引用,也就是说,可以直接在函数的函数体中修改源参数的值,加上const之后,既可以使用引用传递带来的优势,也就是不会执行构造函数,避免了构造带来的成本,也能防止参数在函数体中被意外修改。


类的成员函数后边添加const,只是因为可以禁止在函数中修改掉类的成员变量。


#define 宏定义 在编译预处理的时候,对于程序中出现的宏名,都用宏定义中的字符串去替换,进行宏展开。


内存泄漏:程序在堆上申请了内存之后,在内存的使用范围的最后没有被手动释放,导致这块内存不可用。C/C++一般来使用new delete    malloc free来进行内存的申请和释放。


while(1){} for(;;)


函数的重载:函数的参数的参数类型或者参数个数不相同,但是函数名称相同,称之为函数的重载。


inline函数:被lnline关键字修饰的函数是内联函数。当函数的执行过程耗费时间较少,并且该函数被频繁的调用和使用。可以将之声明为内联函数。


inlint void function(const int& rhs){



}


设计模式:工厂模式、单例模式


虚函数表:函数指针指向不同的函数




class String{
public:
String(const char* str = NULL);
String(const String& rhs);
~String(void);
String& operator=(const String& rhs);
char* GetData();
private:
char* m_data; // 这个题目是有问题的,没有留访问m_data的外部调用函数
}


String::String(const char* str = NULL):
  m_data(str)
  {}


~String::String(void){
if(m_data!=NULL)
delete[] m_data;
}


String::String(const String& rhs){


  unsigned int length = std::strlen(rhs.GetData());
  m_data = new char[length+1];
  strcpy(m_data,rhs.GetData());
}


String& String::operator=(const String& rhs){
if(this==&rhs) return *this;
delete[] m_data;


unsigned int length = std::strlen(rhs.GetData());
  m_data = new char[length+1];
  strcpy(m_data,rhs.GetData());
}




普通函数的回调函数


#include <iostream>


void Function(int rhs) { 

}


void callback(void(*p)(int)) {
p(100);
}


将一个函数的函数指针作为另一个函数的参数传递给这个函数,然后在这个函数的内部调用这个函数。




类的成员函数的回调


typedef std::function<void(int)> _fun;


class Myclass {

public:
void call(int a,_fun b){
b(a);
}
}


class Myclass2{

public:
void callback(int a,int b){


}


void bind(){
_fun fun = std::bind(&Myclass2::callback,this);
Myclass temp;
temp.call(1,fun);

}




C++属于C的超集。有C的效率,也有自己的面向对象的特色。所以有时候在进行C++被叫做c with class。
还有,STL的使用、泛型编程使得C++能够有更灵活的方式去操作不同类型的数据和数据结构,大大的提高了代码的可重用性。




c++和java或者c#不同,java和c#都有自己的垃圾回收机制。而C++是没有的,在堆上申请的内存资源,需要时时刻刻紧盯着,当内存的使用范围结束后,手动需要删除掉。虽然C++也支持智能指针的使用,能够使得人们在操作指针的时候想是在操作类的对象,使用结束后由智能指针负责来析构指针。但是在编码方面,明显还是多于java


引用需要被初始化,而指针不需要。引用初始化之后不能被改变,但是可以改变所指向的对象


std::thread/CreateThread/_beginthread


#define SECOND_PER_YEAR (60*60*24*365)UL


#define MIN(A,B) ((A)>(B)?(A):(B))


int a;
int *a;
int **a;
int a[10];
int *b[10];


默认构造函数,默认析构函数,拷贝函数,赋值函数


#define COMPARE(a,b) ((a)>(b):(a)?(b)) 


内联函数:当函数被频繁使用或者函数的内部执行过程的耗时很短,可以将这个函数声明为inline


抽象类:当子类的某些虚函数没有办法去提炼共性,就可以将基类中的虚函数变为纯虚函数,而这个类就变为抽象类。


引用一个定义过的全局变量:可以包含全局变量所在的头文件,也可以使用extern关键字来实现。


值传递和引用传递或者指针传递


this


继承、多态、泛型编程


编译器自动生成的拷贝构造函数只能执行浅拷贝,无法执行深拷贝。导致两个对象指向同一块内存,有可能会出现被析构两次的情况。


int *p 代表:定义一个名为p的整型指针变量。int (*p)() 指向形如int function() 函数指针。


F10


模板类是代码重用的一种方式。通过模板类这种写法,能够使得代码忽略数据类型。
编译时检查数据类型,保证了类型安全。模板类是平台无关的,可以移植的。


比较耗时的操作可以考虑采用线程的方式执行,并行操作,使用CPU来提高利用率。


c++ 局部变量分配在栈或者堆中。


数据库的日志满了,就表明现在数据库只能执行read,其他Write操作、modify操作均无法执行。


初始化指针变量使用NULL,初始化被内置类型修饰的时候使用0


#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
    #define NULL ((void*)0) 
#endif   
#endif




虚函数并不要求子列重写父类的函数也加virtual

构造函数不能是虚函数,析构函数可以为虚函数,并且一般被设置为虚函数。


//---------------------------------------------------------------------------------------------------------------------------------------------------------


sizeof并不是函数,而是运算符号,而std::strlen不是运算符,是C函数。sizeof不可以被重载,sizeof的参数可以是指针或者内置数据类型等类型,std::strlen的参数只能是const char*类型。char a[10] = {'1',1',1',1',1'}; sizeof(a)的值是10,而std::strlen的值是5,一个计算的结果是全部申请的内存大小,一个是实价占用的内存大小。




std::strlen计算的是字符串的长度,而sizeof计算的是所占字节的大小。


argc char* argv[]其实是main函数的参数。我们可以使用win+R对main函数进行调用。第一个参数是指参数的个数,第二个参数是指传递的字符串。


const在星号的左边还是右边。在星号的左边代表指针指向的变量为常量,在星号的右边代表指针为常量。第一种情况:const int* a = 10; 因此不能对a进行更改,*a = 100是错误的。第二情况:int* const a = 100; 那么,指针a是不能被更改的,a++这类操作是非法的。第三中情况,const int* const a = 100;那么,指针a和指针指向的值都是不能被改变的。
const关键字在类的成员函数的后边没,代表函数内部不能改变类的成员变量,放在函数的前边,代表函数返回的值不能被改变。
在调用函数的时候,一般使用引用传递,但是还要保证参数不被改变,就会使用const来修饰引用类型。


dynamic_cast const_cast static_cast等类型,属于C++的强制类型转换符号。


















































 

























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值