C++ day5 模板、面试题、重载string类

一、day4作业 -- 运算符重载封装string函数 -- 记得再写一遍

用重载运算符封装string类:=表示赋值,+表示产生一个新的字符串(用strcat来实现,不等同于实现strcat),==表示判断是否相等。//这里是我没理解题意,尤其是+重载

c=a+b;  a=b;   c明显是个新的对象,所以返回值用Mystring  

为了便于理解,我又写了个重载+=

#include
#include 
#include 

using namespace std;

class String{
	public:
		String(const char *str) 
		{
			int len = strlen(str)+1;
			ptr = new char [len];
			assert(NULL != ptr);
			strcpy(ptr,str);
		}

		~String()
		{
			delete [] ptr;
		}

	public:
		String operator +(const String &obj)
		{
			int len = strlen(this->ptr) + strlen(obj.ptr) + 1;//计算长度
			char *p = new char [len];
			assert(NULL != p);

			strcpy(p,this->ptr);
			strcat(p,obj.ptr);

			String tmp(p);//构造对象
			delete [] p;

			return tmp;
		}

		String & operator =(const String &obj)
		{
			int len = strlen(obj.ptr)+1;
			delete [] ptr;
			ptr = new char[len];
			assert(NULL != ptr);

			strcpy(this->ptr, obj.ptr);

			return *this;
		}
        String & operator +=(const String &obj)     //重载+=
        {
            int len = strlen(obj.ptr)+strlen(this->ptr)+1;  
            char *p = new char[len];
            strcpy(p,this->ptr);
            strcat(p,obj.ptr);

            delete [] ptr;          
            ptr = new char[len];
            assert(NULL != ptr);
            strcpy(this->ptr, p); 
            delete [] p;

            return *this;
        }


		int operator == (const String &obj)
		{
			return ((strcmp(this->ptr,obj.ptr) == 0) ? 1 : 0);
		}
		int operator != (const String &obj)
		{
			return ((strcmp(this->ptr,obj.ptr) == 0) ? 0 : 1);
		}

		friend ostream & operator << (ostream &, const String &);

	private:
		char *ptr;
};
		
ostream & operator << (ostream &os, const String &obj)
{
	os << obj.ptr;
	
	return os;
}

int main()
{
	String a = "hello";
	String b = "world";
	String c = a+b;
	cout << c << endl;

	a = b;
	cout << a << endl;
	cout << b << endl;

	a = c;

	cout << (a == b) << endl;

	return 0;
}

二、C++面试题

C和C++的结构体区别-能否定义函数
C 不能有函数,但可以有函数指针
C++ 可以有函数,默认权限public
C++的结构体和类的区别--默认权限(继承、成员)
C++结构体 默认public
C++类 默认private
C和C++的区别
面向过程/对象 C主要面向过程,C++主要面向对象(侧重于类的设计而非逻辑)
适用方向不同 C要求效率高代码体积小(如Linux系统就是C编写的),C++适用于更上层
C++是C的扩充
引用和指针的区别
操作方式 指针是存变量地址(间接),引用是取别名(直接)
内存 指针占内存,引用不占内存
指向 指针可以为空且可更改,引用必须初始化且不可更改
指针有多级指针
static在C中的使用
修饰局部变量 延长生命周期,程序结束释放(ps:循环中还能防止重复定义)
修饰全局变量 限制本文件使用(全局变量定义在源.c文件中)
修饰函数 限制本文件使用
C++中值的三种传递方式
值传递 int 
地址传递 int *
引用传递 int &
C和C++中,频繁使用的短小函数怎么实现
C 宏定义(编译阶段)
C++ inline
assert

宏,用于检查不应该发生的情况,比如assert(ptr!=NULL);好用

C中也能用

const相比#define的优点
const更安全 const有数据类型,编译器可以进行安全检查,后者只是单纯的字符替换
const可以调试 宏定义不能
new/delete 与 malloc/free
本质不同 malloc是C/C++库函数,new是C++运算符
C++对象需要

方便编译阶段执行构造函数和析构函数时,创建/释放空间。(而库函数不在编译器的控制权限之内)

new:动态内存分配和初始化

delete:清理和释放内存

内存溢出和泄露
溢出 内存不够导致申请内存失败
泄露 无法成功释放内存,导致内存堆积
malloc(0) 返回一个空指针。检查返回值是否为NULL来判断是否能够正常动态分配内存
解决内存溢出

异常处理函数

if(ptr==NULL)  return -1;或者

assert(ptr!=NULL);

三、函数模板

模板是泛型编程的基础

泛型编程:编写与类无关的代码        //主函数使用举例:add(m,n);

总结:

头部声明:template

外部定义:template

作用域访问符:Demo::

主函数:Demo obj;

      #include
      using namespace std;
      //函数模板声明
      template  //T:int\double\char\Demo...  这里class和类无关
      T add(T &a, T &b);

      class Demo{
         public:
            Demo(int val) : val(val)
            {
               cout << __func__ << ":" << __LINE__ << endl;
            }
         public:
            void setval(int val)
            {
               this->val = val;
            }

            int getval() const
            {
               return this->val;
            }
         private:
            int val;
};
template 
T add(T &a,T &b)
{
    T c = a+b;
    return c;
}

      int main()
      {
         int m = 10;
         int n = 20;

         double d = 1.2;
         double e = 2.3;

         Demo a(333);
         Demo b(333);

         int ret = add(m,n);//T:int
         cout << ret << endl;

         double f = add(d,e);//T:double
         cout << f << endl;

         Demo c = add(a,b);//T:Demo
         cout << c << endl;

         return 0;
      }

四、类模板       

//主函数使用举例:Demo obj(100);创建对象,而非原来的Demo obj(100)

类模板的构造函数不能给定默认值(T都不确定)

总结:

比上个函数模板,区别在于头部声明紧跟类

头部声明:template

外部定义:template

作用域访问符:Demo::

主函数:Demo obj;

#include
using namespace std;
template 
class Demo{
    public:
        Demo(T val):val(val){
            cout << __func__ << ":" << __LINE__ << endl;
        }
        void setval(T val);
        T getval() const;
    private:
        int val;
};
template
void Demo::setval(T val)
{
    this->val = val;
}
template    //外部定义必须加模板声明
int Demo::geival()
{
    return this->val;
}

int main()
{
    Demo obj(100);
    obj.setval(200);
    cout<

五、非类型模板参数

template                

class Demo{

};

//注意index还是用int,不用T

总结:

比上个类模板,头部声明多了确定的参数类型,需要主函数创建对象时初始化

头部声明:template

外部定义:template

作用域访问符:Array::

主函数:Array obj;

#include
#include
using namespace std;
template     //len表示数组长度
class Array{
    public:
        Array(){
            ptr = new T[len];
            assert(ptr!=NULL);
        }
        ~Array(){
            delete [] ptr;
        }
    public:
        void setval(int index,T val);    //index就可以不用T?
        T getval(int index) const;
    private:
        T *ptr;
};
template 
T Array::getval(int index) const
{    
    return ptr[index];
}

int main()
{
    Array a;    //记得主函数用一个整数表示len 
    int i;
    for(i=0;i<10;i++)    //注意这里和数组长度对应
    {
        a.setval(i,i+1);    //还是不习惯对象访问
    }
    for(i=0;i<10;i++)
    {    
        cout<

六、默认类型模板参数

给类模板的形参指定默认值                

template

总结:

比上个非类型模板参数,区别在于头部声明(加具体值)和主函数使用(可覆盖)

头部声明:template

外部定义:template

作用域访问符:Array::

主函数:Array obj;

      #include
      #include
      using namespace std;

      template 
      class Array{
         public:
            Array(){
                ptr = new T[len];
                assert(ptr!=NULL);
            }
            ~Array()
            {
               delete [] ptr;
            }
        public:
            void setval(T val,int pos);
            T getval(int pos) const;
        private:
            T val;
    };
template     
//类外部成员函数定义的时候就不加具体默认值,template
void Array::setval(T val,int pos)    //Array
{
    ptr[index] = val;
}
template 
T Array::getval(int pos) const
{
    return ptr[index];
}

int main()
{
    Array obj;
    Array<> obj2;        //也可以就用默认参数,不传参

    return 0;
}


七、友元模板函数--函数模板作为类模板的友元

#include
using namespace std;
template
class Demo
{
	public:
		Demo(T val) : val(val)
		{
			cout << __func__ << ":" << __LINE__ << endl;
		}
		
		Demo(const Demo &obj) //拷贝构造函数
		{
			cout << __func__ << ":" << __LINE__ << endl;

			this->val = obj.val;
		}

		~Demo()
		{
			cout << __func__ << ":" << __LINE__ << endl;
		}

		void setval(T val)
		{
			this->val = val;
		}

		T getval() const;

		template
		friend ostream &operator <<(ostream &,const Demo &);//友元模板函数

	private:
		T val;
};

//类外部定义成员方法
template
T Demo::getval() const
{
	return this->val;
}

template
ostream &operator <<(ostream &os,const Demo & obj)
{
	os << obj.val;
	return os;
}


int main()
{
	Demo obj(666);
	Demo obj1 = obj;

	cout << obj << endl;
	cout << obj1 << endl;

	Demo obj2(1.2);
	cout << obj2 << endl;


	return 0;
}

头部声明:template

内部friend函数声明:template friend

外部定义:template

外部friend函数定义:template

作用域访问符:Demo::

主函数:Demo obj;

你可能感兴趣的:(c++,c#,学习)