大气装饰公司网站源码,做网站商城开发什么语言最快,学网络技术培训学校,黑帽seo优化推广一.对象特性#xff08;续#xff09;
1.空指针访问成员函数
C中空指针也是可以调用成员函数的#xff0c;但是也要注意有没有用到this指针。
如果用到this指针#xff0c;需要加以判断保证代码的健壮性。 如果调用的成员函数不访问成员属性#xff0c;那么空指针可以调…一.对象特性续
1.空指针访问成员函数
C中空指针也是可以调用成员函数的但是也要注意有没有用到this指针。
如果用到this指针需要加以判断保证代码的健壮性。 如果调用的成员函数不访问成员属性那么空指针可以调用对应的成员函数如果该函数涉及了成员属性那么就相当于涉及了 this指针空指针的话调用涉及成员属性的函数需要进行this的判断加以保证代码的健壮性。 if(thisNULL)return;2.const修饰成员函数 const 成员变量的用法和普通 const 变量的用法相似只需要在声明时加上 const 关键字。初始化const成员变量只有一种方法就是通过构造函数的初始化列表这点在前面已经提过了。 常函数
成员函数后加const后我们称为这个函数为常函数常函数内不可以修改成员属性成员属性声明时加关键字mutable后在常函数中依然可以修改
常对象:
声明对象前加const称该对象为常对象常对象只能调用常函数 需要强调的是必须在成员函数的声明和定义处同时加上const关键字。 最后再来区分一下 const 的位置 函数开头的 const 用来修饰函数的返回值表示返回值是 const 类型也就是不能被修改例如const char * getname()。函数头部的结尾加上 const 表示常成员函数这种函数只能读取成员变量的值而不能修改成员变量的值例如char * getname() const 二.友元
生活中你的家有客厅(Public)有你的卧室(Private)。客厅所有来的客人都可以进去但是你的卧室是私有的也就是说只有你能进去 但是呢你也可以允许你的好闺蜜好基友进去。在程序里有些私有属性 也想让类外特殊的一些函数或者类进行访问就需要用到友元的技术。
::: tip 总结
友元的目的就是让一个函数或者类访问另一个类中私有成员 友元的关键字为 friend
::: 友元函数的三种实现方式 全局函数做友元类做友元成员函数做友元 1.全局函数作友元
#includeiostream
using namespace std;
#includestringclass Building {friend void func(Building* p);
public: string bighall;
private:string bedroom;
public:Building() {bighall 大厅;bedroom 卧室;}
};//全局函数
void func(Building *p) {cout 好闺蜜正在访问 p-bighall endl;cout 好闺蜜正在访问 p-bedroom endl;
}void test01() {Building *p1 new Building();func(p1);
}
int main() {test01();return 0;
}2.友元类
#includeiostream
using namespace std;
#includestringclass Building {friend class Goodgay; //声明友元类
public:string bighall;
private:string bedroom;
public:Building();
};class Goodgay {
public:Goodgay();void visit(Building *p);Building * building;
};Goodgay::Goodgay() {building new Building;
}Building::Building() {bighall 大厅;bedroom 卧室;
}void Goodgay::visit(Building* p) {cout 好闺蜜正在访问 p-bighall endl;cout 好闺蜜正在访问 p-bedroom endl;
}void test01() {Building *p1 new Building();Goodgay gf1;gf1.visit(p1);
}
int main() {test01();return 0;
}3.成员函数做友元
#includeiostreamusing namespace std;#includestringclass Goodgay;class Building;class Building {friend void Goodgay::visit();public:string bighall;
private:string bedroom;
public:Building();};class Goodgay {
public:Goodgay();void visit();Building *building;
};Goodgay::Goodgay() {building new Building;
}Building::Building() {bighall 大厅;bedroom 卧室;
}void Goodgay::visit() {cout 好闺蜜正在访问 building-bighall endl;cout 好闺蜜正在访问 building-bedroom endl;
}void test01() {Building *p new Building;Goodgay gf1;gf1.visit();
}int main() {test01();return 0;
}注意成员函数作友元时必须把先定义的类的成员函数作为后定义的类的友元如果二者调换顺序会报错。 三.类的补充理解
1.作用域
类其实也是一种作用域每个类都会定义它自己的作用域。在类的作用域之外普通的成员只能通过对象可以是对象本身也可以是对象指针或对象引用来访问静态成员既可以通过对象访问又可以通过类访问而typedef定义的类型只能通过类来访问。
2.class与struct的区别
C中保留了C语言的 struct 关键字并且加以扩充。在C语言中struct 只能包含成员变量不能包含成员函数。而在C中struct 类似于 class既可以包含成员变量又可以包含成员函数。
C中的 struct 和 class 基本是通用的唯有几个细节不同
使用 class 时类中的成员默认都是 private 属性的而使用struct时结构体中的成员默认都是 public 属性的。class 继承默认是 private 继承而 struct 继承默认是 public 继承.。class 可以使用模板而 struct 不能。
四.string类型
1.string定义
string 是 C 中常用的一个类它非常重要我们有必要在此单独讲解一下。
使用 string 类需要包含头文件string下面的例子介绍了几种定义 string 变量对象的方法
#include iostream
#include string
using namespace std;int main(){string s1;string s2 c plus plus;string s3 s2;string s4 (5, s);return 0;
}变量 s1 只是定义但没有初始化编译器会将默认值赋给 s1默认值是也即空字符串。
变量 s2 在定义的同时被初始化为c plus plus。与C风格的字符串不同string 的结尾没有结束标志\0。
变量 s3 在定义的时候直接用 s2 进行初始化因此s3的内容也是c plus plus。
变量 s4 被初始化为由 5 个s字符组成的字符串也就是sssss。
从上面的代码可以看出string 变量可以直接通过赋值操作符进行赋值。string 变量也可以用C风格的字符串进行赋值例如s2 是用一个字符串常量进行初始化的而 s3 则是通过 s2 变量进行初始化的。 与C风格的字符串不同当我们需要知道字符串长度时可以调用 string 类提供的 length() 函数。 虽然 C 提供了 string 类来替代C语言中的字符串但是在实际编程中有时候必须要使用C风格的字符串例如打开文件时的路径为此string 类为我们提供了一个转换函数 c_str()该函数能够将 string 字符串转换为C风格的字符串并返回该字符串的const指针const char*。请看下面的代码
string path D:\\demo.txt;
FILE *fp fopen(path.c_str(), rt);string 字符串也可以像C风格的字符串一样按照下标来访问其中的每一个字符。string 字符串的起始下标仍是从 0 开始。 2.字符串拼接
有了 string 类我们可以使用或运算符来直接拼接字符串非常方便再也不需要使用C语言中的 strcat()、strcpy()、malloc() 等函数来拼接字符串了再也不用担心空间不够会溢出了。
用来拼接字符串时运算符的两边可以都是 string 字符串也可以是一个 string 字符串和一个C风格的字符串还可以是一个 string 字符串和一个字符数组或者是一个 string 字符串和一个单独的字符。
#includeiostream
using namespace std;
#includestringint main() {string s1 hello ;string s2 word! ;char s3[] friend ;cout s1 s2 endl;cout s1 s3 endl;cout s1 s2 s3 endl;return 0;
}3.插入字符串
insert() 函数可以在 string 字符串中指定的位置插入另一个字符串它的一种原型为
string insert (size_t pos, const string str);pos 表示要插入的位置也就是下标str 表示要插入的字符串它可以是 string 字符串也可以是C风格的字符串。
int main(){string s1, s2, s3;s1 s2 1234567890;s3 aaa;s1.insert(5, s3);cout s1 endl;s2.insert(5, bbb);cout s2 endl;return 0;
}4.删除字符串
erase() 函数可以删除 string 中的一个子字符串。它的一种原型为
string erase (size_t pos 0, size_t len npos);pos 表示要删除的子字符串的起始下标len 表示要删除子字符串的长度。如果不指明len的话那么直接删除从pos到字符串结束处的所有字符。
int main(){string s1, s2, s3;s1 s2 s3 1234567890;s2.erase(5);s3.erase(5, 3);cout s1 endl;cout s2 endl;cout s3 endl;return 0;
}5.提取子字符串
substr() 函数用于从 string 字符串中提取子字符串它的原型为
string substr (size_t pos 0, size_t len npos) const;pos 为要提取的子字符串的起始下标len 为要提取的子字符串的长度。
6.字符串查找
6.1find函数
find() 函数用于在 string 字符串中查找子字符串出现的位置它其中的一种原型为
size_t find (const string str, size_t pos 0) const;第一个参数为待查找的子字符串它可以是 string 字符串也可以是C风格的字符串。第二个参数为开始查找的位置下标如果不指明则从第0个字符开始查找。 find() 函数最终返回的是子字符串第一次出现在字符串中的起始下标。如果没有查找到子字符串那么会返回 string::npos它是 string 类内部定义的一个静态常成员用来表示 size_t 类型所能存储的最大值。 6.2rfind函数 rfind() 和find()很类似同样是在字符串中查找子字符串不同的是 find() 函数从第二个参数开始往后查找而rfind()函数则最多查找到第二个参数处如果到了第二个参数所指定的下标还没有找到子字符串则返回 string::npos。 6.3find_first_of() 函数
find_first_of() 函数用于查找子字符串和字符串共同具有的字符在字符串中首次出现的位置。
#include iostream
#include string
using namespace std;
int main(){string s1 first second second third;string s2 asecond;int index s1.find_first_of(s2);if(index s1.length())coutFound at index : index endl;elsecoutNot foundendl;return 0;
}运行结果 Found at index : 3
本例中 s1 和s2共同具有的字符是‘s’该字符在 s1 中首次出现的下标是3故查找结果返回3。
五.对象知识点总结
类的成员有成员变量和成员函数两种。
成员函数之间可以互相调用成员函数内部可以访问成员变量。
私有成员只能在类的成员函数内部访问。默认情况下class 类的成员是私有的struct 类的成员是公有的。
可以用“对象名.成员名”、“引用名.成员名”、“对象指针-成员名”的方法访问对象的成员变量或调用成员函数。成员函数被调用时可以用上述三种方法指定函数是作用在哪个对象上的。
对象所占用的存储空间的大小等于各成员变量所占用的存储空间的大小之和如果不考虑成员变量对齐问题的话。
定义类时如果一个构造函数都不写则编译器自动生成默认无参构造函数和复制构造函数。如果编写了构造函数则编译器不自动生成默认构造函数。一个类不一定会有默认构造函数但一定会有复制构造函数。
任何生成对象的语句都要说明对象是用哪个构造函数初始化的。即便定义对象数组也要对数组中的每个元素如何初始化进行说明。如果不说明则编译器认为对象是用默认构造函数或参数全部可以省略的构造函数初始化。在这种情况下如果类没有默认构造函数或参数全部可以省略的构造函数则编译出错。
对象在消亡时会调用析构函数。
每个对象有各自的一份普通成员变量但是静态成员变量只有一份被所有对象所共享。静态成员函数不具体作用于某个对象。即便对象不存在也可以访问类的静态成员。静态成员函数内部不能访问非静态成员变量也不能调用非静态成员函数。
常量对象上面不能执行非常量成员函数只能执行常量成员函数。
包含成员对象的类叫封闭类。任何能够生成封闭类对象的语句都要说明对象中包含的成员对象是如何初始化的。如果不说明则编译器认为成员对象是用默认构造函数或参数全部可以省略的构造函数初始化。
在封闭类的构造函数的初始化列表中可以说明成员对象如何初始化。封闭类对象生成时先执行成员对象的构造函数再执行自身的构造函数封闭类对象消亡时先执行自身的析构函数再执行成员对象的析构函数。
const 成员和引用成员必须在构造函数的初始化列表中初始化此后值不可修改。
友元分为友元函数和友元类。友元关系不能传递。
成员函数中出现的 this 指针就是指向成员函数所作用的对象的指针。因此静态成员函数内部不能出现 this 指针。成员函数实际上的参数个数比表面上看到的多一个多出来的参数就是 this 指针。