收费网站设计,p2p网站制作流程,站酷网vi设计,群晖 wordpress 性能创作过程中难免有不足#xff0c;若您发现本文内容有误#xff0c;恳请不吝赐教。 提示#xff1a;以下是本篇文章正文内容#xff0c;下面案例可供参考 一、构造函数
问题1 关于编译器生成的默认成员函数#xff0c;很多童鞋会有疑惑#xff1a;不实现构造函数的情况下… 创作过程中难免有不足若您发现本文内容有误恳请不吝赐教。 提示以下是本篇文章正文内容下面案例可供参考 一、构造函数
问题1 关于编译器生成的默认成员函数很多童鞋会有疑惑不实现构造函数的情况下编译器会 生成默认的构造函数。但是看起来默认构造函数又没什么用 d 对象调用了编译器生成的默认构造函数但是d 对象 _year/_month/_day 依旧是随机值。也就说在这里 编译器生成的 默认构造函数并没有什么用 解答C 把类型分成内置类型 ( 基本类型 ) 和自定义类型。内置类型就是语言提供的数据类 型如 int/char... 自定义类型就是我们使用 class/struct/union 等自己定义的类型看看下面的程序就会发现编译器生成默认的构造函数会对自定类型成员_t 调用的它的默认构造函数。 示例1 #includeiostream
using namespace std;class A
{
public:A(int a){cout Aint(a) endl;_a a;}
private:int _a;
};class Date
{
public://Date(int year, int month, int day)//{// _year year;// _month month;// _day day;//}
private://内置类型int _year;int _month;int _day;//自定义类型A _aa;
};int main()
{Date d1;
} class A没有提供默认构造函数(不用参数就可以调用的构造). 示例2 #includeiostream
using namespace std;class A
{
public:A(int a 0){cout A int(a) endl;_a a;}
private:int _a;
};class Date
{
public://Date(int year, int month, int day)//{// _year year;// _month month;// _day day;//}
private://内置类型int _year;int _month;int _day;//自定义类型A _aa;
};int main()
{Date d1;
} 如果A不提供默认构造需要使用初始化列表才能解决。当前的学习暂时先通过提供全缺省( A(int a 0) )来解决这个问题. 简单来说我们不写编译器生成的默认构造函数对内置类型不做处理对自定义类型会调用它的默认构造. 二、默认构造函数 无参的构造函数和全缺省的构造函数都称为默认构造函数并且默认构造函数只能有一个。 注意无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数都可以认为是默认构造函数。 特点不传参就可以调用的构造就是默认构造. 三、析构函数 可以简单理解为与构造函数相反的函数类比Destroy函数. 日期类不需要写析构函数因为日期类没有资源需要清理年、月、日属于对象不需要清理。而像栈这种才需要清理有指向资源才需要清理。 示例1 内置类型的成员不做处理造成堆上的空间没有释放造成内存泄漏。
#includeiostream
using namespace std;typedef int DataType;
class Stack
{
public:Stack(size_t capacity 3){_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}void Push(DataType data){_array[_size] data;_size;}/*~Stack(){cout ~Stack() endl;free(_array);_array nullptr;_size _capacity 0;}*/
private:// 内置类型DataType* _array;int _capacity;int _size;};void TestStack()
{Stack s;s.Push(1);s.Push(2);
}int main()
{TestStack();return 0;
} 示例2
自定义类型的成员会去调用他的析构。
#includeiostream
using namespace std;class A
{
public:A(int a 0){cout A(int a) endl;_a a;}~A(){cout ~A() endl;}
private:int _a;
};typedef int DataType;
class Stack
{
public:Stack(size_t capacity 3){_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}void Push(DataType data){_array[_size] data;_size;}/*~Stack(){cout ~Stack() endl;free(_array);_array nullptr;_size _capacity 0;}*/
private:// 内置类型DataType* _array;int _capacity;int _size;// 自定义类型A _aa;
};void TestStack()
{Stack s;s.Push(1);s.Push(2);
}int main()
{TestStack();return 0;
} 四、拷贝构造
日期类拷贝
#includeiostream
using namespace std;
typedef int DataType;
class Stack
{
public:Stack(size_t capacity 3){_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}void Push(DataType data){_array[_size] data;_size;}~Stack(){cout ~Stack() endl;free(_array);_array nullptr;_size _capacity 0;}
private:// 内置类型DataType* _array;int _capacity;int _size;
};class Date
{
public:Date(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout _year / _month / _day / endl;}
private://内置类型int _year;int _month;int _day;
};void func1(Date d)
{d.Print();
}int main()
{Date d1(2025,1,8);func1(d1);return 0;
} 栈拷贝
#includeiostream
using namespace std;
typedef int DataType;
class Stack
{
public:Stack(size_t capacity 3){_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}void Push(DataType data){_array[_size] data;_size;}~Stack(){cout ~Stack() endl;free(_array);_array nullptr;_size _capacity 0;}
private:// 内置类型DataType* _array;int _capacity;int _size;
};class Date
{
public:Date(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout _year / _month / _day / endl;}
private://内置类型int _year;int _month;int _day;
};void func1(Date d)
{d.Print();
}void func2(Stack s)
{}int main()
{Date d1(2025,1,8);func1(d1);Stack s1;func2(s1);return 0;
} 解决方法
void func2(Stack s)
{//使用引用
} 拷贝构造函数 定义只有单个形参该形参是对本类类型对象的引用(一般常用const修饰)在用已存 在的类类型对象创建新对象时由编译器自动调用 。 自定义类型传值传参要调用拷贝构造。 特征1 拷贝构造函数是构造函数的一个重载形式。 特征2 拷贝构造函数的参数只有一个且必须是类类型对象的引用使用传值方式编译器直接报错 因为会引发无穷递归调用。 #includeiostream
using namespace std;class Date
{
public:Date(int year, int month, int day){cout Date(Date d) endl;_year year;_month month;_day day;}Date(Date d){_year d._year;_month d._month;_day d._day;}void Print(){cout _year / _month / _day / endl;}
private://内置类型int _year;int _month;int _day;
};int main()
{Date d1(2025,1,8);Date d2(d1);return 0;
} Date(Date d){//没有引用会引发无穷递归调用_year d._year;_month d._month;_day d._day;} #includeiostream
using namespace std;typedef int DataType;
class Stack
{
public:Stack(size_t capacity 3){_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}Stack(Stack s){cout Stack(Stack s) endl;// 深拷贝_array (DataType*)malloc(sizeof(DataType) * s._capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}memcpy(_array, s._array, sizeof(DataType) * s._size);_size s._size;_capacity s._capacity;}void Push(DataType data){_array[_size] data;_size;}~Stack(){cout ~Stack() endl;free(_array);_array nullptr;_size _capacity 0;}
private:// 内置类型DataType* _array;int _capacity;int _size;
};void func2(Stack s)
{s.Push(1);
}int main()
{Stack s1;func2(s1);Stack s2(s1);return 0;
} 问题 如果不写拷贝构造函数系统会自动生成吗 #includeiostream
using namespace std;class Date
{
public:Date(int year 1, int month 1, int day 1){_year year;_month month;_day day;}void Print(){cout _year / _month / _day endl;}private:int _year;int _month;int _day;
};typedef int DataType;
class Stack
{
public:Stack(size_t capacity 3){cout Stack() endl;_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}void Push(DataType data){_array[_size] data;_size;}~Stack(){cout ~Stack() endl;free(_array);_array nullptr;_size _capacity 0;}
private:DataType* _array;int _capacity;int _size;
};int main()
{Date d1(2025, 1, 1);Date d2 d1;Stack st1;Stack st2(st1);return 0;
} 特征3 若未显式定义编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按 字节序完成拷贝这种拷贝叫做浅拷贝或者值拷贝。 我们不写编译默认生成的拷贝构造跟之前的构造函数特性不一样 1、内置类型 值拷贝 2、自定义的类型调用他的拷贝 总结Date不需要我们实现拷贝构造默认生成就可以用 Stack需要我们自己实现深拷贝的拷贝构造默认生成会出问题 MyQueue对于默认生成的几个函数非常受用人生赢家 #includeiostream
using namespace std;typedef int DataType;
class Stack
{
public:Stack(size_t capacity 3){cout Stack() endl;_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}Stack(const Stack s){cout Stack(Stack s) endl;// 深拷贝_array (DataType*)malloc(sizeof(DataType) * s._capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}memcpy(_array, s._array, sizeof(DataType) * s._size);_size s._size;_capacity s._capacity;}void Push(DataType data){_array[_size] data;_size;}~Stack(){cout ~Stack() endl;free(_array);_array nullptr;_size _capacity 0;}
private:DataType* _array;int _capacity;int _size;
};class MyQueue
{
private:Stack _pushst;Stack _popst;
};int main()
{MyQueue mq1;MyQueue mq2 mq1;return 0;
} 注意 Date(const Date d){//一般情况都加上constcout Date(Date d) endl;_year d._year;_month d._month;_day d._day;}Date(const Date d){cout Date(Date d) endl;//若不小心写反了很容易忽视这里的错误d._year _year ;d._month _month;d._day _day;} 五、运算符重载 问题1 日期对象如何比较大小能否用 . 简单的代码实现 #includeiostream
using namespace std;class Date
{
public:Date(int year 1, int month 1, int day 1){_year year;_month month;_day day;}void Print(){cout _year / _month / _day endl;}//private:int _year;int _month;int _day;
};bool DateLess (const Date x1,const Date x2)
{if (x1._year x2._year){return true;}else if (x1._year x2._year x1._month x2._month){return true;}else if (x1._year x2._year x1._month x2._month x1._day x2._day){return true;}else{return false;}
}int main()
{Date d1(2025, 1, 1);Date d2(2025, 1, 11);coutDateLess(d1, d2)endl;return 0;
} #includeiostream
using namespace std;class Date
{
public:Date(int year 1, int month 1, int day 1){_year year;_month month;_day day;}void Print(){cout _year / _month / _day endl;}//private:int _year;int _month;int _day;
};bool operator(const Date x1, const Date x2)
{if (x1._year x2._year){return true;}else if (x1._year x2._year x1._month x2._month){return true;}else if (x1._year x2._year x1._month x2._month x1._day x2._day){return true;}else{return false;}
}int main()
{Date d1(2025, 1, 1);Date d2(2025, 1, 11);cout (d1 d2) endl;cout (operator(d1, d2)) endl;return 0;
} 写为成员函数 // d1 d2
// d1.operator(d2)
//操作数顺序不能随便换
bool operator(const Date d){if (_year d._year){return true;}else if (_year d._year _month d._month){return true;}else if (_year d._year _month d._month _day d._day){return true;}else{return false;}} 运算符复用 class Date
{
public:Date(int year 1, int month 1, int day 1){_year year;_month month;_day day;}void Print(){cout _year / _month / _day endl;}bool operator(const Date d){if (_year d._year){return true;}else if (_year d._year _month d._month){return true;}else if (_year d._year _month d._month _day d._day){return true;}else{return false;}}bool operator(const Date d){return _year d._year _month d._month _day d._day;}// d1 d2bool operator(const Date d){return *this d || *this d;}bool operator(const Date d){return !(*this d);}bool operator(const Date d){return !(*this d);}bool operator!(const Date d){return !(*this d);}
} 实现日期运算 #includeiostream
using namespace std;class Date
{
public:Date(int year 1, int month 1, int day 1){_year year;_month month;_day day;}void Print(){cout _year / _month / _day endl;}int GetMonthDay(int year, int month){int monthArray[13] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };if (month 2 ((year % 4 0 year % 100 ! 0) || (year % 400 0))){return 29;}return monthArray[month];}//如果写成Date operator(int day)会发现Date ret d1 50;中d1也会改变所以该写成Date operator(int day){_day day;while (_day GetMonthDay(_year, _month)){// 月进位_day - GetMonthDay(_year, _month);_month;// 月满了if (_month 13){_year;_month 1;}}return *this;}Date operator(int day) //出了作用域对象不在了不能用引用返回{Date tmp(*this);tmp day;return tmp;//tmp._day day;//while (tmp._day GetMonthDay(tmp._year, tmp._month))//{// // 月进位// tmp._day - GetMonthDay(tmp._year, tmp._month);// _month;// // 月满了// if (tmp._month 13)// {// tmp._year;// tmp._month 1;// }//}//return tmp;}private:// 内置类型int _year;int _month;int _day;
};int main()
{Date d1(2023, 7, 21);Date d2(2022, 8, 21);Date ret d1 50;ret.Print();d1.Print();return 0;
} 总结 以上就是今天要讲的内容本文仅仅简单介绍了c的基础知识。