C++ 面向对象编程中,类和继承的使用十分重要,有效地提高了代码复用,减少了编写程序时因代码冗余而产生的不必要的错误。
在类的继承中,最常用的是 public 继承。
注意事项
1.派生类操作基类成员
派生类可以访问基类中所有的++非私有成员++。因此基类成员如果不想被派生类的成员函数直接访问,则应在基类中声明为 private,换句话说,如果希望在继承之后,基类中的部分成员仍能被派生类的方法访问和控制,则可将基类中的这部分成员定义为 protected 或者 public。
但因为 public 声明的类成员是公有的,在程序的任何地方都可以通过类的实例直接访问,所以其封装性和私密性大大降低,所以建议将这部分成员声明为 protected,这样,这部分属性只能在类内和派生类中被访问和控制。
示例:
目前需求是这样的:先定义了一个名为 claDataSubject 的类,用于存储程序所需要使用的数据,而数据是通过读取 txt 文件得到的,所以 claDataSubject 中的成员属性即是存储数据的变量,成员方法即是读取 txt 文件时用到的各种方法。如下所示:
struct stcSample {
long long lonSampleId;
std::vector<double> vecdouAttribute;
int intPredictClass;
};
class claDataSubject {
protected:
int intInvalidPropertyCol;
int intLabelCol;
std::map<int, std::string> mapAttrId2AttrName;
std::map<std::string, int> mapAttrName2AttrId;
std::vector<struct stcSample> vecstcSample;
public:
claDataSubject();
~claDataSubject() {}
void initialize();
void readDataAttrNameFile(const std::string& filePath);
void readDataSetFile(const std::string& filePath);
void testAfterReadInData();
};
上面这个类只实现了读取和存储数据,下面要编写各种运算和操作这些数据的方法,为了提高程序的可读性和可维护性,所以想到了将这些方法重新写到一个名为 claClusteringAlgorithm 的类中,因为要操作如上数据,所以 claClusteringAlgorithm 应该是 claDataSubject 的子类。
可以看到 claDataSubject 类中的数据成员结构很复杂,有 vector、map、struct 等等,如果将这些数据成员声明为 private,则在派生类 claClusteringAlgorithm 中无法直接访问控制这些数据,只能通过在基类 claDataSubject 中编写类似于 get 和 set 函数,然后在派生类中调用这些函数来实现间接访问控制数据成员,这样会使 claDataSubject 更加复杂,所以想到了将 claDataSubject 的数据成员声明为 protected,这样派生类就可以直接访问控制了。
2.继承之后基类中的构造函数
一个派生类继承了所有的基类方法,但以下情况除外:
- 基类的构造函数、析构函数和拷贝构造函数
- 基类的重载运算符
- 基类的友元函数
原本我在基类 claDataSubject 的公有函数中编写了存储数据的代码,现在通过公有继承定义了派生类 claClusteringAlgorithm ,则在实例化派生类 claClusteringAlgorithm 时仍会调用基类的构造函数。示例如下:
基类的构造函数:
Clustering::claDataSubject::claDataSubject()
{
std::cout << "\t********** Base Class **********" << std::endl << std::endl;
std::cout << "\tBegin to initialize data object . . .\n" << std::endl;
initialize();
std::cout << "\tFinish initialization\n" << std::endl;
}
程序运行时: