1.valarray模板类
#include <iostream>
#include <valarray>
using namespace std;
int main(int argc, const char * argv[]) {
// valarray模板类
valarray<int> array1{20,30,40};
cout << array1.size() << endl; // 3
cout << array1.sum() << endl; // 90
cout << array1.max() << endl; // 40
valarray<int> array2{60,70,80};
array1.swap(array2); // 两个数组所有元素进行交换
cout << array2[1] << endl; // 30
valarray<int> array3{10};
array1.swap(array3);
cout << array1.size() << endl; // 1
cout << array3.size() << endl; // 3
return 0;
}
2.成员变量的初始化顺序
#include <iostream>
using namespace std;
class MyClass
{
public:
int code1;
int code2;
//MyClass() : code1(20), code2(code1) // 父类可以在构造方法后面初始化成员变量,code2是20,先初始化code1,在初始化code2
MyClass() : code2(30), code1(code2) // 在构造方法后面初始化成员变量时,初始化顺序和变量的前后顺序无关,和变量的定义顺序有关
{
//cout << code2 << endl;
cout << code1 << endl; // 0 code2默认值是0
}
};
int main(int argc, const char * argv[]) {
// 成员变量的初始化顺序
MyClass myClass;
return 0;
}
3.C++中的单件模式(Singleton)
#include <iostream>
using namespace std;
class SingletonClass
{
private:
int mCode;
static SingletonClass* instance; // 定义了一个静态指针,指向SingletonClass类型的对象,用于检测SingletonClass类是否被定义,如果未被定义,则instance为空指针
SingletonClass()
{
}
SingletonClass(int code)
{
mCode = code;
}
public:
static SingletonClass* getInstance()
{
if(instance == nullptr)
{
instance = new SingletonClass();
}
return instance;
}
static SingletonClass* getInstance(int code) // 重载
{
if(instance == nullptr)
{
instance = new SingletonClass(code); // 这里调用了private里的构造方法SingletonClass
}
return instance;
}
string getName()
{
return "Bill";
}
};
SingletonClass* SingletonClass::instance = nullptr; // 类的静态变量要在类的外部进行初始化,这里的前面是调用了构造方法,构造了一个指向SingletonClass的指针
int main(int argc, const char * argv[]) {
// 单件模式(Singleton),获得一个类的唯一实例
// 1. 不能使用new创建对象,也不能直接定义类变量————放到private里面
// 2. 至少需要提供一个静态的方法,用于返回唯一的对象实例
SingletonClass* instance1 = SingletonClass::getInstance(); // ::的效果和->应该是一样的
cout << instance1->getName() << endl; // Bill
SingletonClass* instance2 = SingletonClass::getInstance(123); // 这里123不会传给mCode,因为instance在之前已经被定义,不为空了,在if判断时不再成立
if(instance1 == instance2)
{
cout << "instance1 == instance2" << endl; // 二者是相等的,因为instance2没有另外new空间
}
// SingletonClass *singletonClass = new SingletonClass();
return 0;
}
4.explicit与单参数的构造方法
#include <iostream>
using namespace std;
class Integer
{
private:
int mValue;
public:
// 构造方法不需要返回数值
explicit Integer(int value)
{
mValue = value;
}
int getValue()
{
return mValue;
}
};
int main(int argc, const char * argv[]) {
// explicit与构造方法
//Integer n = 20; //加了explicit后这句话会报错,如果不加,这句话的作用就相当于Integer n = Integer(20);
Integer n = Integer(20); // Integer(20)
cout << n.getValue() << endl; // 20
return 0;
}
5.私有(private)继承
#include <iostream>
using namespace std;
class ParentClass
{
private:
int mCode = 20;
public:
int getCode()
{
return mCode;
}
};
class ParentClass1
{
private:
int mCode1 = 20;
public:
int getCode1()
{
return mCode1;
}
};
class SubClass : private ParentClass,private ParentClass1 // 私有继承
{
public:
int code = getCode();
ParentClass& getParentClass() // 返回引用
{
return *this;
}
};
int main(int argc, const char * argv[]) {
// 公有继承中,在子类中可以使用父类public的方法、变量,且这些方法、变量在子类中也是public,可以在类外访问
// 私有继承,父类中所有public内容在子类中都相当于potected类型,只能在子类中访问,不能在外部访问
SubClass subClass;
// cout << subClass.getCode() << endl;
cout << subClass.code << endl; // 20,code是subClass自己的public值
cout << subClass.getParentClass().getCode() << endl; // 20,这里如果直接用subClass.getCode()会报错,因为是私有继承,getCode()是父类的方法,在子类相当于protect类型,在外部不能调用,而经由getParentClass()后,用this指针返回了父类,所以就可以使用getCode()了
return 0;
}
6.避免操作符重载造成的递归调用
#include <iostream>
using namespace std;
class String
{
private:
string mStr = "hello";
public:
friend ostream& operator<<(ostream& os, const String& str); // 设置操作符重载函数为友元函数,可以访问私有类型变量
};
ostream& operator<<(ostream& os, const String& str) // 对输出流操作符进行重载
{
return os << str.mStr;
}
class NewString : public String
{
};
ostream& operator<<(ostream& os, const NewString& str)
{
return os << "NewString:" << (String&)str; // 这里str为子类,需要转换为父类,否则会无限的递归,循环的加载重载后的“<<”操作符,不停的打印:NewString:
}
int main(int argc, const char * argv[]) {
// 避免操作符重载造成的递归调用
NewString newString;
cout << newString << endl; // 这里会调用重载后的“<<”操作符,打印:NewString:hello
return 0;
}
7.保护(protected)继承
#include <iostream>
using namespace std;
class ParentClass
{
private:
int mCode = 20;
public:
int getCode()
{
return mCode;
}
};
class SubClassPrivate : private ParentClass
{
public:
int code = getCode(); // 继承来的父类的东西都变成私有的了,外部没有办法访问,即,如果再有一个子类,去继承SubClassPrivate ,那么是没法用getCode()的
};
class SubClassProtected : protected ParentClass
{
// 如果再有一个子类,去继承SubClassProtected ,还可以访问getCode()
};
class MyClass1 : public SubClassProtected
{
public:
int code = getCode();
};
class MyClass2 : public SubClassPrivate
{
public:
//int code = getCode(); // 报错
};
int main(int argc, const char * argv[]) {
// 保护(protected)继承,在衍生出第三代类的时候,会有区别
return 0;
}
8.使用using重新定义访问权限
#include <iostream>
using namespace std;
class ParentClass
{
private:
int mCode = 50;
public:
int code = 10;
int getCode()
{
return 30;
}
int operator[](string key) // 操作符重载
{
if(key == "code")
{
return code;
}
else
{
return -1;
}
}
};
class SubClass : private ParentClass // 私有继承
{
public:
// 这里想在外部访问父类内容还有一种方法,就是在本子类定义一个方法,return父类的内容
using ParentClass::code; // 这样使用using之后就能在外部使用该父类内容了
using ParentClass::getCode; // 对于函数使用using时,不需要写返回值类型啥的
using ParentClass::operator[];
// using ParentClass::mCode; // using是无法将父类中原本的私有成员转换成public的
};
int main(int argc, const char * argv[]) {
// 使用using重新定义访问权限
SubClass subClass;
cout << subClass.getCode() << endl; // 30
cout << subClass.code << endl; // 10
cout << subClass["code"] << endl; // 10
cout << subClass["abc"] << endl; // -1
return 0;
}
9.C++中的多继承
#include <iostream>
using namespace std;
class Person
{
public:
string name;
int age;
};
ostream& operator<<(ostream& os, Person& person) // 重载 输出Person类的操作符
{
return os << "姓名:" << person.name << " 年龄:" << person.age;
}
class Teacher
{
public:
int code;
string school;
string specialty;
};
ostream& operator<< (ostream& os, Teacher& teacher) // 重载 输出Teacher类的操作符
{
return os << "职工编号:" << teacher.code << " 学校:" << teacher.school << " 专业:" << teacher.specialty;
}
class Professor:public Person, public Teacher // 多继承
{
public:
string title;
};
ostream& operator<<(ostream& os, Professor& professor) // 重载 输出Professor类的操作符
{
return os << (Person&)professor << endl << (Teacher&)professor << endl << "职称:" << professor.title;
} // (Person&)professor是输出professor所具有的Person相对应的属性,(Teacher&)professor同理
int main(int argc, const char * argv[]) {
// 多继承(multiple inheritance,MI)
Professor p;
p.name = "王军";
p.age = 40;
p.code = 25;
p.school = "清华大学";
p.specialty = "计算机";
p.title = "教授";
cout << p << endl;
return 0;
}
10.多继承与共同基类的问题
#include <iostream>
using namespace std;
class BaseClass
{
};
class ParentClass1 : public BaseClass
{
};
class ParentClass2 : public BaseClass // ParentClass2 与 ParentClass1 有共同基类
{
};
class SubClass : public ParentClass1, public ParentClass2 // 多继承
{
};
int main(int argc, const char * argv[]) {
// 虚继承(虚基类)
SubClass* subClass = new SubClass(20);
BaseClass* baseClass = (ParentClass1*)subClass; //可以通过这样的方式指定一下父类,就可以划等号了
// BaseClass* baseClass = subClass; // 会报错,因为subClass继承了两个baseClass的内容,所以二者不能这样划等号
return 0;
}
11.虚基类(虚继承)
#include <iostream>
using namespace std;
class BaseClass
{
private:
int mValue1;
public:
BaseClass(int value1) // 构造方法,如果不定义,则有一个默认的没有参数的构造方法
{
mValue1 = value1;
cout << "BaseClass" << endl;
}
};
class ParentClass1 : virtual public BaseClass // BaseClass 是ParentClass1 的虚基类
{
private:
int mValue2;
public:
ParentClass1(int value2) : BaseClass(value2) // 子类构造方法 调用了父类的构造方法
{
mValue2 = value2;
cout << "ParentClass1" << endl;
}
};
class ParentClass2 : public virtual BaseClass
{
private:
int mValue2;
public:
ParentClass2(int value2) : BaseClass(value2)
{
mValue2 = value2;
cout << "ParentClass2" << endl;
}
};
class SubClass : public ParentClass1, public ParentClass2
{
private:
int mValue;
public:
SubClass(int value) : BaseClass(value),ParentClass1(value), ParentClass2(value)
{
mValue = value;
}
};
int main(int argc, const char * argv[]) {
// 虚继承(虚基类)
SubClass* subClass = new SubClass(20);
// subClass的父类定义了虚基类,此时就可以划等号了,
// C++编译器会自动选取一个父类的基类给subClass继承,而不是有几个父类,就继承几个BaseClass
BaseClass* baseClass = subClass; // 调用了一次BaseClass(通过subClass直接调用的祖先类),
// 一次ParentClass1(通过subclass调用的父类,但是这个父类在调用他的父类时,发现使用的是虚继承,前面已经调用了一次Basecalss的内容了,所以在此不再调用Baseclass),
// 一次ParentClass2(和ParentClass2同理)
return 0;
}
12.多继承与父类方法冲突
#include <iostream>
using namespace std;
class ParentClass1
{
protected:
virtual void show()
{
cout << "ParentClass1" << endl;
}
};
class ParentClass2
{
protected:
virtual void show()
{
cout << "ParentClass2" << endl;
}
};
class SubClass : public ParentClass1, public ParentClass2 // 多继承,ParentClass1和ParentClass2都有一个show方法,所以在SubClass调用show方法时,要注意冲突问题
{
public:
/* void show()
{
ParentClass1::show();
cout << "SubClass" << endl;
}*/
void show1()
{
ParentClass1::show();
}
void show2()
{
ParentClass2::show();
}
};
int main(int argc, const char * argv[]) {
// 多继承与父类方法冲突
SubClass subClass;
subClass.show1();
subClass.show2();
// ParentClass1 *parentClass1 = new SubClass();
// parentClass1->show(); // 此句结合上句,调用的是SubClass中的show(因为subclass中的show方法覆盖了parentClass1中的show方法),subclass中没有show方法时,且parentClass1中的show是public类时,调用parentClass1中的show
return 0;
}