1、c++类的构造和析构?
构造函数: 1、定义与类名相同的成员函数叫构造函数
2、构造函数在定义时可以有参数
3、没有任何返回类型的声明
析构函数:1、清理对象的函数,没有参数也没有任何返回类型的声明
2、在对象销毁时自动调用
先创建的对象后析构,类没有提供构造函数c++编译器会自动给你提供一个默认的构造函数,类没有提供拷贝构造函数,c++会提供一个默认的拷贝构造函数,
拷贝函数调用时机:
1、Test(const Test &obj)
Test t1(1,2);
Test t2(3,4);
Test t3 =t1;//用t1来初始化t3 会调用拷贝构造函数
t2 =t1;//用t1给t2赋值,不会调用拷贝构造函数会调用 operator =()
赋值操作和初始化是两个不同的概念。
2、第二种调用时机
Test t1(1,2);
Test t2(t1);//用t1对象初始化t2对象 时会调用拷贝构造函数
3、第三种调用时机
当类的对象当作实参传给形参时,调用拷贝构造函数
Test t1(1,2);
void Gets(Test t);
Gets(t1);//会调用拷贝构造函数
4、第四种调用时机
void play ()
{
Test t1;
t1 =g();//用返回的匿名对象赋值给另外一个同类型的对象,那么匿名对象被析构,
Test t2 = g();
//用返回的匿名对象,来初始化另外一个同类型的对象,那么匿名对象会直接转成新的对象,会调用拷贝构造函数,匿名对象不会析构掉
}
Test g()
{
Test a(1,2);
return a;//返回匿名对象
}
构造函数执行顺序:先构造的后析构,后构造的先析构,它相当于一个栈,先进后出。
2、delete和delete[]的区别
new 和 delete是操作符,free和malloc是c/c++的标准函数库
delete 释放new分配的单个对象指针指向的内存
delete[] 释放new分配的对象数组指针指向的内存
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。
new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。 基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[] 回收空间。
3、指针和引用的区别
(1)、指针可以赋予空值,引用不可以赋值空值且当被创建的时候必须初始化,
(2)、指针的指向可以改变,当应用初始化后不可以改变,
(3)、sizeof指针 得到的为指针本身的大小,在32位系统中为4个字节,sizeof引用的字节大小为引用对象的大小
(4)、指针有多级指针,引用只有一级
(5)、指针和引用的自增++运算意义不一样
4、代码定义了一个常量指针和一个指向常量的指针,问2个指针有什么区别?
常量指针是指指针本身是常量,指向的对象是变量
指向常量的指针是指:指针本身是变量,指向的对象是常量
5、string 类的成员函数补全,包括3种构造函数和一种=的运算符重载。
#include <iostream>
#include <string.h>
#include "String.h"
using namespace std;
String::String()
{
str_ = new char['\0'];
cout << "default construct String!" << endl;
}
String::String(char *str)
{
cout << "construct String!" << endl;
int len = strlen(str) + 1;
str_ = new char[len];
memset(str_, 0, len);
strcpy(str_, str)
}
String::String(const String& other)
{
int len = strlen(other.str_) + 1;
str_ = new char[len];
memset(str_, 0, len);
strcpy(str_, other.str_);
}
String& String::operator=(const String& other)
{
if(this == &other)
{
return *this;
}
int len = strlen(other.str_) + 1;
delete [] str_;
str_ = new char[len];
memset(str_, 0, len);
strcpy(str_, other.str_);
return *this;
}
String& String::operator=(char *str)
{
delete [] str_;
int len = strlen(str) + 1;
str_ = new char[len];
memset(str_, 0, len);
strcpy(str_, str);
return *this;
}
char& String::operator[](unsigned int index)
{
//return str_[index];
return const_cast<char&>(static_cast<const String&>(*this)[index]);
}
const char& String::operator[](unsigned int index) const
{
return str_[index];
}
String operator+(const String& s1, const String& s2)
{
#if 0
int len = strlen(s1.str_) + strlen(s2.str_) + 1;
char *newptr = new char[len];
memset(newptr, 0, len);
strcpy(newptr, s1.str_);
strcat(newptr, s2.str_);
String tmp(newptr);
#endif
String tmp(s1);
tmp += s2;
return tmp;
}
String& String::operator+=(const String& s)
{
int len = strlen(s.str_) + strlen(str_) + 1;
char *newptr = new char[len];
memset(newptr, 0, len);
strcpy(newptr, str_);
strcat(newptr, s.str_);
String tmp(newptr);
delete [] str_;
str_ = new char[len];
strcpy(str_, newptr);
return *this;
}
ostream& operator<<(ostream& out, const String& s)
{
out << s.str_;
return out;
}
istream& operator>>(istream& in, String& s)
{
char buffer[4096];
in >> buffer;
s.str_ = buffer;
return in;
}
String::~String()
{
cout << "destroy String!" << endl;
}
void String::Display()
{
cout << "str = " << str_ << endl;
}
#include <iostream>
#include "String.h"
using namespace std;
int main()
{
String s1("hello");
s1.Display();
String s2(s1);
//String s2;
//s2.Display();
#if 0
String s3;
s3 = s1;
//s3 = "hello";
s3.Display();
//#endif
s1[1] = 'E';
s1.Display();
#endif
String s3("world");
#if 0
s3 += s1;
s3.Display();
cin >> s2;
cout << s2 << endl;
#endif
s3 = s1 + s2;
s3.Display();
return 0;
}
#ifndef _STRING_H_
#define _STRING_H_
#endif
#include <iostream>
using namespace std;
class String
{
public:
String();
String(char *str);
String(const String& other);
~String();
String& operator=(char *str);
String& operator=(const String& other);
char& operator[](unsigned int index);
const char& operator[](unsigned int index) const;
friend String operator+(const String& s1, const String& s2);
String& operator+=(const String& s);
friend ostream& operator<<(ostream& out, const String& s);
friend istream& operator>>(istream& in, String& s);
void Display();
private:
char *str_;
};
6、编号1-n的人围成1圈,数到m的人站出来,直到所有人站出来,求站出来的人的序列(key:细节处理)
#include"stdafx.h"
#include<iostream>
struct ChainNode
{
int data;
ChainNode* next;
};
//编号为1-n的人,数到m的人站出来,求站出来的人的序列(key:细节处理)
int main()
{
int n, m;
cin >> n >> m;
//create circularList
int len = n;
ChainNode* headNode = new ChainNode;
ChainNode* pNode = headNode;
while (n--)
{
pNode->data = len - n;
if (n) //不需要的不申请
{
pNode->next = new ChainNode;
pNode = pNode->next;
}
}
pNode->next = headNode;
pNode = pNode->next;
//print order
int rest = len;
while (rest) //用rest判断而不用pNode判断,链表是否为空用指针无法判断
{
int cot = m - 2;
while (cot--)
{
pNode = pNode->next;
}
cout << pNode->next->data << endl;
ChainNode* tmp = pNode->next;
pNode->next = pNode->next->next;
delete tmp;
rest--;
pNode = pNode->next;
}
return 0;
}