当前位置: 首页 > news >正文

青海哪家做网站的公司最大徐州网站定制公司

青海哪家做网站的公司最大,徐州网站定制公司,国外网站建设现状,网站被镜像怎么做写在前面 拷贝构造函数、赋值运算符重载、取地址运算符都是属于类的默认成员函数#xff01; 默认成员函数是程序猿不显示声明定义#xff0c;编译器会中生成。 在程序编写中#xff0c;我们也经常使用拷贝的方式来获取到对应的值#xff0c;例如整形变量拷贝int a 0; i…写在前面 拷贝构造函数、赋值运算符重载、取地址运算符都是属于类的默认成员函数 默认成员函数是程序猿不显示声明定义编译器会中生成。 在程序编写中我们也经常使用拷贝的方式来获取到对应的值例如整形变量拷贝int a 0; int b a;等等。在程序的编写中我们也会需要进行对象的拷贝这样来获取到对应对象的值。 文章目录 写在前面一、拷贝构造函数1.1、若未显式定义编译器会生成默认的拷贝构造函数。 二、运算符重载2.1、赋值运算符重载(类的默认成员函数)2.2、重载运算符中的特殊前置和后置的重载2.3、流插入与流提取的重载运算符2.4、重载取地址操作符是类的默认成员 一、拷贝构造函数 拷贝构造函数只有单个形参该形参是对本类类型对象的引用(一般常用const修饰)在用已存在的类类型对象创建新对象时由编译器自动调用。是一个构造函数 拷贝构造函数也是特殊的成员函数其特征如下 拷贝构造函数是构造函数的一个重载形式。拷贝构造函数的参数只有一个且必须是类类型对象的引用使用传值方式编译器直接报错因为会引发无穷递归调用。 我们先创建一个标准的拷贝构造函数 class Date { public:Date() {cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}Date(const Date d1) { //拷贝构造函数_year d1._year;_month d1._month;_day d1._day;}private:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2024,1,1);printf(d1:);d1.Print();Date d2(d1);printf(d2:);d2.Print();return 0; }程序运行结果 如果我们不使用类引用作为参数而是使用传值的方式作为参数的话会导致无穷递归调用 class Date { public:Date() {cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}Date(Date d1) { //拷贝构造函数使用传值方式_year d1._year;_month d1._month;_day d1._day;}private:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2024,1,1);printf(d1:);d1.Print();Date d2(d1);printf(d2:);d2.Print();return 0; }我们知道函数参数使用传值那么形参就是实参的一份临时拷贝。 C规定的拷贝 内置类型直接拷贝自定义类型必须调用该自定义类型对应的拷贝构造函数完成拷贝。 此时形参是stack类的对象我们实参也是stack类的对象d1形参接收就需要进行拷贝而这个时候又涉及到了类的拷贝那么也是调用stack类的拷贝构造函数但是拷贝构造函数又时需要传值……无限套娃如下图 程序运行结果 编译器会检查拷贝构造函数是否正确的编写。 在拷贝构造中参数要加上const加上const的好处 防止在拷贝构造中写反导致原对象被修改为其他值。如果原对象是const修饰的对象也可以进行拷贝构造不会造成权限放大。可以作为传值返回函数的接收对象。 class Date { public:Date() {//cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}Date(const Date d1) {cout Date(const Date d1) endl;_year d1._year;_month d1._month;_day d1._day;}private:int _year 1;int _month 1;int _day 1; };Date getDate() {Date d(2222, 1, 1);return d; }int main() {Date d1(2022, 5, 4);Date d2 getDate();return 0; }在拷贝构造的形参中加入const后就可以使用getDate();函数的返回值作为拷贝构造的形参。我们知道函数的返回值返回的是一个临时变量临时变量中具有常性。所以我们在拷贝构造函数中加入const 后就可以接收常性的参数 1.1、若未显式定义编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝这种拷贝叫做浅拷贝或者值拷贝。 拷贝构造对类型的处理 对内置类型成员进行值拷贝/浅拷贝对自定义类型成员会调用它的拷贝构造函数 当类中的属性全部都是内置类型成员我们可以使用默认生成的拷贝构造函数完成拷贝操作 我们把Date类自己编写的拷贝构造删除后尝试使用默认的拷贝构造函数。 class Date { public:Date() {cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}private:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2024,1,1);printf(d1:);d1.Print();Date d2(d1);printf(d2:);d2.Print();return 0; }程序运行结果 在上图中我们也可以看出程序没有编写拷贝构造函数使用默认拷贝构造函数也完成了任务。但这并不代表可以一直使用默认构造函数。 我们使用stack类来尝试一下默认拷贝构造函数是否可以完成我们预想的结果。 class stack { public:stack(int defintCapacity 4) {_arr (int*)calloc(defintCapacity, sizeof(int));if (nullptr _arr){perror(malloc申请空间失败);return;}_capacity defintCapacity;_size 0;}stack(int* arr, int defintCapacity) {if (nullptr arr) {perror(malloc申请空间失败);return;}_arr arr;_capacity defintCapacity;_size 0;}void push(int x) {//....扩容等_arr[_size] x;}~stack() {free(_arr);_arr nullptr;} private:int* _arr;int _size;int _capacity; };int main() {stack s1;stack s2(s1);return 0; }程序运行结果 因为在默认的拷贝构造函数对象按内存存储按字节序完成拷贝在拷贝结束后发现 s2对象的_arr数组地址和s1对象的_arr数组地址一样。这时候我们如果我们往s2存储内容也会改变s1对象的内容这不是我们想要的而且在对象结束生命周期之后对象会自动调用自己对应的析构函数。这时候析构函数就多次释放同一个空间程序崩溃如下图。 使用浅拷贝的内存图布局如下图 要解决这种问题就需要涉及深拷贝(不才后面会专门写一篇笔记)下面代码是针对这种情况的特殊解决办法。 class stack { public:stack(int defintCapacity 4) {_arr (int*)calloc(defintCapacity, sizeof(int));if (nullptr _arr){perror(malloc申请空间失败);return;}_capacity defintCapacity;_size 0;}stack(int* arr, int defintCapacity) {if (nullptr arr) {perror(malloc申请空间失败);return;}_arr arr;_capacity defintCapacity;_size 0;}stack(stack s) { //需要程序猿自己编写拷贝构造函数(深拷贝)_arr (int*)calloc(s._capacity, sizeof(int));if (nullptr _arr){perror(malloc申请空间失败);return;}memcpy(_arr, s._arr, s._capacity * sizeof(int));_capacity s._capacity;_size s._size;}void push(int x) {//....扩容等_arr[_size] x;}~stack() {free(_arr);_arr nullptr;} private:int* _arr;int _size;int _capacity; };我们解决了内置类型拷贝构造的问题后我们自定义类型是否需要每个都写拷贝构造函数呢 我们使用栈实现队列 class stack { public:stack(int defintCapacity 4) {_arr (int*)calloc(defintCapacity, sizeof(int));if (nullptr _arr){perror(malloc申请空间失败);return;}_capacity defintCapacity;_size 0;}stack(int* arr, int defintCapacity) {if (nullptr arr) {perror(malloc申请空间失败);return;}_arr arr;_capacity defintCapacity;_size 0;}void push(int x) {//....扩容等_arr[_size] x;}~stack() {free(_arr);_arr nullptr;}stack(stack s) {_arr (int*)calloc(s._capacity, sizeof(int));if (nullptr _arr){perror(malloc申请空间失败);return;}memcpy(_arr, s._arr, s._capacity * sizeof(int));_capacity s._capacity;_size s._size;} private:int* _arr;int _size;int _capacity; };class MyQueue{private:stack s1;stack s2; };int main() {stack s1;s1.push(1);s1.push(2);s1.push(3);stack s2(s1);return 0; }程序运行结果 这时MyQueue类就不需要编写拷贝构造因为在MyQueue对象进行拷贝时会自动调用stack类的拷贝构造。不写拷贝构造函数与不需要写构造函数与析构函数的逻辑是一样的。拷贝构造函数的形参也尽可能的加上const修饰权限范围这样可以防止形参对象的属性被修改而且也可以防止实参的权限放大的问题 二、运算符重载 C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数其中在自定义类型中所有的运算符都需要程序员进行运算符重载 日期类比较大小 class Date { public:Date() {cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}public:int _year 1;int _month 1;int _day 1; };bool Less(const Date s1, const Date s2) {if (s1._year s2._year) {return true;}else if (s1._year s2._year s1._month s2._month) {return true;}else if (s1._year s2._year s1._month s2._month s1._day s2._day) {return true;}return false; }bool Larger(const Date s1, const Date s2) {if (s1._year s2._year) {return true;}else if (s1._year s2._year s1._month s2._month) {return true;}else if (s1._year s2._year s1._month s2._month s1._day s2._day) {return true;}return false; } int main() {Date d1(2022,5,4); Date d2(2022,5,5);cout Less(d1, d2) endl;cout Larger(d1, d2) endl;return 0; }在我们自定义的日期类中我们想比较两个类的大小只能通过函数的形式来比较如果函数命名不规范时我们难以比较 所以在C中增加了赋值运算符重载方便程序猿的使用 运算符重载关键字operator后面接需要重载的运算符符号。 我们使用运算符重载来改善上述代码 class Date { public:Date() {cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}public:int _year 1;int _month 1;int _day 1; };bool operator(const Date s1, const Date s2) {if (s1._year s2._year) {return true;}else if (s1._year s2._year s1._month s2._month) {return true;}else if (s1._year s2._year s1._month s2._month s1._day s2._day) {return true;}return false; }bool operator(const Date s1, const Date s2) {if (s1._year s2._year) {return true;}else if (s1._year s2._year s1._month s2._month) {return true;}else if (s1._year s2._year s1._month s2._month s1._day s2._day) {return true;}return false; } int main() {Date d1(2022, 5, 4);Date d2(2022, 5, 5);cout operator(d1, d2) endl;cout operator(d1, d2) endl;return 0; }我们只需要把函数名修改为operator和operator。这样就完成了 和的运算符重载。我们在main函数中调用也是如此使用operator和operator来调用此函数。但是这样就和我们编写函数没什么区别。 运算符重载的作用是可以直接在main函数中使用和 来进行比较。如下 int main() {Date d1(2022, 5, 4);Date d2(2022, 5, 5);cout operator(d1, d2) endl;cout operator(d1, d2) endl;printf(\n);cout (d1 d2) endl;cout (d1 d2) endl;return 0; }程序运行结果 虽然我们是使用了和来进行比较但是我们通过operater来重载和后我们就可以直接使用和来进行比较。本质上还是使用operator和operator来调用此函数编译器会自己处理的过程。如下图 这时operater重载的和是全局的对类中的属性要求就一定是public类型如果是私有的就无法访问所以我们要重载类对象的和时可以把operater函数作为类的成员函数。 运算符重载必须使用满足C对运算符重载的规定 不能通过连接其他符号来创建新的操作符比如operator重载操作符必须有一个类类型参数即不能全部都是内置类型比如bool operator(int a ,int b){...}用于内置类型的运算符其含义不能改变例如内置的整型不能改变其含义如改为减…作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this.* ::(域作用限定符) sizeof ?:(三目) . 注意以上5个运算符不能重载。 我们把上述例子的全局运算符重载函数改为Date类的内置成员函数。 class Date { public:Date() {cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}bool operator(const Date s2) {if (_year s2._year) {return true;}else if (_year s2._year _month s2._month) {return true;}else if (_year s2._year _month s2._month _day s2._day) {return true;}return false;}bool operator( const Date s2) {if (_year s2._year) {return true;}else if (_year s2._year _month s2._month) {return true;}else if (_year s2._year _month s2._month _day s2._day) {return true;}return false;} public:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2022, 5, 4);Date d2(2022, 5, 5);cout (d1 d2) endl;cout (d1 d2) endl;printf(\n);cout d1.operator(d2) endl;cout d1.operator(d2) endl;return 0; }作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this而且作为类成员函数重载时就算属性是私有的我们也可以进行比较。类成员函数重载时在main函数中也可以直接使用和来进行比较编译器最终也是会转换为d1.operator(d2) 2.1、赋值运算符重载(类的默认成员函数) 赋值运算符重载与 拷贝构造函数不同处 拷贝构造函数适用于用一个已经存在的对象初始化另外一个对象。赋值运算符重载函数适用于已经存在的两个对象之间赋值拷贝。 class Date { public:Date() {cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}Date(const Date d1) {cout Date(const Date d1) endl;_year d1._year;_month d1._month;_day d1._day;}void Print(){cout _year - _month - _day endl;}bool operator(const Date s2) {if (_year s2._year) {return true;}else if (_year s2._year _month s2._month) {return true;}else if (_year s2._year _month s2._month _day s2._day) {return true;}return false;}bool operator(const Date s2) {if (_year s2._year) {return true;}else if (_year s2._year _month s2._month) {return true;}else if (_year s2._year _month s2._month _day s2._day) {return true;}return false;}void operator(const Date s2) {_year s2._year;_month s2._month;_day s2._day;} public:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2022, 5, 4);Date d2(2000, 1, 1);d1 d2;return 0; }程序运行结果 程序运行结果没有问题但是我们在内置类型赋值的时候可以连续赋值的如int a,b; ab12;但是我们把赋值运算符重载的返回值设置了void程序运行不了连续赋值的结果。如下图 我们可以把返回值设置为Date类作为返回值。如下程序 Date operator(const Date s2) {_year s2._year;_month s2._month;_day s2._day;return *this; }这样我们就可以完成连续赋值的处理如下图 但是我们直接使用传值返回会造成大量无用的拷贝构造这样会对性能造成一点影响 我们就可以把传值返回改为传引用返回。虽然this指针是形参会随着函数的生命周期结束而销毁但是我们可以把*this作为返回这样我们返回的是对象的地址对象的生命周期不会随着函数的生命周期结束而销毁。 Date operator(const Date s2) {_year s2._year;_month s2._month;_day s2._day;return *this; }程序运行结果 d1 d2其底层与d1.operator(d2)是一样的当然在使用重载赋值运算符时程序猿会出现自己与自己赋值的情况。这时候我们可以在重载运算符中加入自己给自己赋值的条件判断。这样可以避免自己给自己赋值。 Date operator(const Date s2) {if (this ! s2) {_year s2._year;_month s2._month;_day s2._day;}return *this; }赋值运算符重载格式 参数类型 const T传递引用可以提高传参效率**返回值类型**T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值检测是否自己给自己赋值返回*this 要复合连续赋值的含义 因为赋值运算符重载是类的默认成员函数即用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。 注意编译器默认生成的赋值运算符重载函数内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。与拷贝构造的行为一样。 需要注意的是编译器生成的赋值运算符拷贝是逐字节拷贝即浅拷贝的方式。 遇到指针等相关拷贝的情况需要程序猿编写深拷贝。 赋值运算符只能重载成类的成员函数不能重载成全局函数 原因赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值运算符重载只能是类的成员函数。 2.2、重载运算符中的特殊前置和后置的重载 在重载运算符中有前置和后置两个特殊的运算符重载。因为在程序中这两个运算符的函数名都是一样的。需要函数重载来区别前置和后置。(重载运算符--同理) 我们先实现前置还是使用上述的Date类为例。 class Date { public:Date() {//cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}Date(const Date d1) {cout Date(const Date d1) endl;_year d1._year;_month d1._month;_day d1._day;}void Print(){cout _year - _month - _day endl;}bool operator(const Date s2) {if (_year s2._year) {return true;}else if (_year s2._year _month s2._month) {return true;}else if (_year s2._year _month s2._month _day s2._day) {return true;}return false;}bool operator(const Date s2) {if (_year s2._year) {return true;}else if (_year s2._year _month s2._month) {return true;}else if (_year s2._year _month s2._month _day s2._day) {return true;}return false;}Date operator(const Date s2) {_year s2._year;_month s2._month;_day s2._day;return *this;}Date operator() {//前置_day;return *this;//因为是前置可以把加完后的结果直接当做返回值。}public:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2022, 5, 4);d1;d1.Print();return 0; }程序运行结果 operator()因为是自增不需要参数所以我们把形参列表设为空。 我们把operator()当做为前置但后置也是相同的函数名operator所以在C中我们在后置的形参中增加一个参数让其形成函数重载以达到前置和后置的区别。 但是 是自增不需要接收任何形参但是需要完成函数重载所以我们只需要在形参列表中增加一个int类型即可完成重载该类型可以不添加变量名称。如下 Date operator() {//前置_day;return *this;//因为是前置可以把加完后的结果直接当做返回值。}Date operator(int) {//后置Date d1 *this;//因为是后置加加所以要把原来的结果先储存为一个临时变量。之后我们才可以进行自增处理_day;return d1;//返回的是临时变量的值。}后置中operator(int)的int参数不是为了接收具体的值。仅仅是占位跟前置构成函数重载。 其中前置和后置的调用会由编译器区分。我们程序员不需要理会如何进行调用。 在我们程序员自己编写的前置和后置中。会有性能的区别。因为 后置需要进行拷贝构造创建一个临时变量来作为返回值而且也是传值返回。但是在内置类型的或--中性能区别不大。 2.3、流插入与流提取的重载运算符 在上面例中我们Date类对象的内容打印是使用print函数来进行Date类属性的显示为了更好的打印我们可以使用流的重载运算符来进行自定义类型的打印。 不才在文档查询网站中查询到cin是istream类的对象和cout是osterem类的对象那么我们在Date类中就可以通过istream类和osterem类来自定义引用对象来进行标准输入输出。 我们先以打印为例即重载运算符。 class Date { public:Date() {//cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}Date(const Date d1) {cout Date(const Date d1) endl;_year d1._year;_month d1._month;_day d1._day;}void operator(ostream out) {out _year 年 _month 月 _day 日;}private:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2022, 5, 4);//d1.Print();cout d1;Date n1 d1;//n1.Print();cout d1 endl n1 endl;return 0; }运行结果 因为我们是把重载运算符写入了类中成为了类的方法所以我们直接使用cout d1是无法访问的cout d1其本质是cout.operator(d1)我们在库中是没有自定义类型重载的。如下图所以我们在Date类中重载的运算符需要d1 cout这样来使用因为这才符合d1.operator(cout)的函数调用 但是d1.operator(cout)明显不符合我们是使用习惯但是在类中第一个形参默认是this指针无法改变的。所以我们就把operator定义在类外面作为全局函数。 作为全局重载运算符函数时我们久可以把第一个参数设置为ostrem第二次参数设置为我们自定义类型Date这样久可以完成cout d1的使用。如下图 此时虽然cout d1没有报错但是我们类中的属性时私有的为了访问到我们私有的属性我们在类中可以把全局重载运算符函数operater声明为友元函数。(不才后面会专门出一篇笔记讲解) class Date {friend void operator(ostream out, const Date d1);//把operator函数声明为友元函数public:Date() {//cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}Date(const Date d1) {//cout Date(const Date d1) endl;_year d1._year;_month d1._month;_day d1._day;}private:int _year 1;int _month 1;int _day 1; };void operator(ostream out, const Date d1) {out d1._year 年 d1._month 月 d1._day 日; }在类中声明前加上friend关键字声明void operator(ostream out, const Date d1)函数时友元函数。 运行结果 和之前的运算符重载函数相同我们为了多次运用我们的返回值久设置为ostrem这样我们就可以实现复合使用cout d1 endl。又因为cout是iostream创建的对象而且cout的生命周期是程序的声明周期所以我们可以把ostream设置为ostream引用返回 ostream operator(ostream out, const Date d1) {out d1._year 年 d1._month 月 d1._day 日;return out; }运行结果 同理流插入也是如此 istream operator(istream in, Date d1) {in d1._year d1._month d1._day;return in; }也需要在类中声明为友元函数。 2.4、重载取地址操作符是类的默认成员 因为也只是取地址所以函数设计就可以非常简单。只需要返回值是类类型指针。返回值是this指针即可 Date* operator() {cout Date* operator() endl;return this; }如果遇到const修饰的话,我们也需要this指针设置为const成员而且返回值也是const类类型指针。如下程序 const Date* operator() const {cout Date* operator() const endl;return this;}编译器会根据是否为const修饰的对象来调用对应的取地址运算符重载函数。 class Date { public:Date() {//cout Date() endl;}Date(int year, int month, int day) {_year year;_month month;_day day;}Date(const Date d1) {//cout Date(const Date d1) endl;_year d1._year;_month d1._month;_day d1._day;}Date* operator() {cout Date* operator() endl;return this;}const Date* operator() const {cout Date* operator() const endl;return this;}private:int _year 1;int _month 1;int _day 1; };int main() {Date d1(2022, 5, 4);const Date d2(200, 1, 1);Date* pd1 d1;const Date* pd2 d2;return 0; }程序运行结果为: 重载取地址运算符并没有什么实际上的作用。因为属于类的默认成员函数不需要程序员写会默认生成。所达到的效果是一样的。 以上就是本章所有内容。若有勘误请私信不才。万分感激 如果对大家有用的话就请多多为我点赞收藏吧~~~ ps:表情包来自网络侵删
http://www.dnsts.com.cn/news/201797.html

相关文章:

  • 宁波专业建设网站建站公司惠州网络推广专员
  • 个人网站备案号可以做企业网站吗网站后台建设教程
  • iis内网站设置允许脚本执行甜蜜定制app
  • 爱网站查询挖掘工具南通旅游网站建设
  • 湛江网站营销友妙招链接
  • 网站开发课程技术培训凡科做的网站能被收录吗
  • 商务网站策划方案免费海外网络连接器
  • html5网站建设基本流程图wordpress 获取用户密码
  • 如何做一个静态网站给境外网站网站做代理
  • 陈坤做直播在哪个网站定制开发响应式网站
  • 无锡网站建设外包优势网站备案和不备案有什么区别
  • 事业单位网站建设计划十大互联网企业排名
  • 做个网站 一般费用wordpress排版教程
  • 高新快速建设网站电话龙岩优化seo排名
  • 如何给网站做2维码金坛城乡建设管理网站
  • 惠州网站建设推广百度开发者搜索
  • 商丘网站制作公司一二三网络推广郑州网站专业建设qq
  • 中小学生教育网站建设方案邯郸营销型网站建设
  • 网站建设合同续签申请书做的网站没流量吗
  • 建站培训免费下载ppt的网站
  • 做百度网站需要多少钱美团做团购网站
  • 深圳知名网站设计公司排名迪士尼网站是谁做的
  • 建材网站模板嵌入式软件开发价格
  • 购买的网站平台建设服务计入杭州婚恋网站建设
  • 收录优美图片官网优化课程设置
  • 网站免费下载app做互联网营销一般上什么网站
  • 我是做网站怎么赚钱wordpress自动加p标签
  • 视频网站中滑动列表怎么做的ps在线网页版
  • 部门网站建设存在的问题乐清网站只做
  • 青岛三吉互联网站建设公司客户关系管理软件