[Linux]C++学习笔记(四)

[Linux]C++学习笔记(四)

在学习C++类的定义之前,先要知道一个类的成员与成员函数所具有的访问权限问题,也就是通常说的访问修饰符。

C++中,对类的成员和成员函数进行访问权限的设置时,具有默认、public、private和protected四种访问修饰符,简单介绍如下:

默认情况下,不加任何修饰,它表示该类的成员或成员函数是私有的,即与private等价。

public是公共访问修饰符,它所修饰的成员或者成员函数,不仅该类内部的其他成员函数可以访问由public修饰的成员或者成员函数,而且不属于该类的其他类的成员或者成员函数都可以访问。

private是私有访问修饰符,它所修饰的成员或者成员函数,对于该类来说是可以随意访问,即该类的任何成员函数都可以访问;但是对于不属于该类的成分,例如另一个其它的不同的类,没有任何权限访问,也就是说这个其他类根本看不到。另外,甚至对该类的派生类也不能够访问到该类的私有成员或成员函数。

protected是受保护修饰符,它所修饰的成员或者成员函数,对于该类及其该类的派生类来说,都是可以访问的,而对于除了该类和该类的派生类以外的其它任何类都没有权限访问。

关于对类的成员或成员函数进行访问的问题,C++中还可以定义友元函数,这就为外部另一个函数可以访问该类的成员函数提供了可能,从而通过成员函数间接操作类的数据成员,这也应该算是一种访问修饰符。

下面定义并实现一个C++类,类名称为Filter。对于Filter类,设计思想如下:

该类包含一个区间,作为类的私有数据成员,包括区间的下界lower_limit和上界upper_limit,另外,为了实现Filter类的过滤功能,假设扫描某个字符串,统计某个字符在一个容器中每个字符串中出现的次数,再定义一个字符成员some_char。

关于类的行为,假设存在一个过滤的行为,由函数filter来实现,可见它应该是public公共的,同时对于扫描一个字符串并统计指定字符出现的次数,是类的内部使用的函数,假设为scan,并声明为private私有的。

根据上面的描述,定义类如下所示:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Filter {
        public:
                Filter();
                Filter(const char some, const int lower, const int upper);
                void filter(vector<string>& container);
                ~Filter();
        private:
                int scan(string& s);
        private:
                char some_char;
                int lower_limit;
                int upper_limit;
};

首先引入STL的string和vector,因为要把待过滤的字符串放到容器中,然后迭代容器,对每个字符串进行过滤。

公有行为:

有一个默认的构造函数,没有任何参数;另一个具有参数的构造函数,参数分别是指定字符、区间下界、区间上界;filter函数对传入的vector容器执行过滤操作;最后一个是析构函数。

私有行为:

scan函数是私有的,只能被该类使用,实现对一个字符串进行扫描,统计指定字符出现的次数。每次从vector中迭代出一个字符串,就调用scan函数统计一次。

私有成员:

也就是该类的私有数据,some_char是指定的字符,lower_limit是区间下界,upper_limit是区间上界。

实现Filter类,如下所示:

Filter::Filter() : lower_limit(0), upper_limit(0) {
}

Filter::Filter(const char some, const int lower, const int upper) : some_char(some), lower_limit(lower), upper_limit(upper) {
}

void Filter::filter(vector<string>& container) {
        vector<string> v;
        vector<string>::iterator it = container.begin();
        while(it!=container.end()) {
                int count = scan(*it);
                if(count>=lower_limit && count<=upper_limit) {
                        v.push_back(*it);
                }
                it++;
        }
        container = v;
}

int Filter::scan(string& s) {
        string::size_type size = s.size();
        int count = 0;
        string::size_type pos = s.find(some_char, 0);
        while(pos != string::npos) {
                count++;
                if(pos == size-1) {
                        break;
                }
                else {
                        pos = s.find(some_char, pos+1);
                }
        }
        return count;
}

Filter::~Filter() {
}

测试主函数如下所示:

int main() {
        vector<string> vtr;
        vtr.push_back("123455897328455545"); // 5:6
        vtr.push_back("55555555555555555"); // 5:17
        vtr.push_back("000998766532245"); // 5:2
        vtr.push_back("1234998989893422"); // 5:0
        vtr.push_back("0000055005500000"); // 5:4
        vtr.push_back("888888436455532554"); // 5:5
        cout<<vtr.size()<<endl;
        char some = '5';
        int lower = 5;
        int upper = 12;
        Filter *pfilter = new Filter(some, lower, upper);
        pfilter->filter(vtr);
        cout<<vtr.size()<<endl;

        vector<string>::iterator it;
        for(it=vtr.begin(); it!=vtr.end(); it++) {
                cout<<*it<<endl;
        }

        delete pfilter;
        return 0;
}

在容器中放入6个数字字符串,统计每个字符串出现字符'5'的个数,预期结果是,过滤掉5的个数不在区间[5, 12]的字符串,最后应该只有2个满足区间要求。

测试结果:

[root@bogon class]# g++ -o class class.cpp
[root@bogon class]# ./class
6
2
123455897328455545
888888436455532554

最后,看一下C++中实例化一个类的方法。

例如,对上面的Filter,我可以实例化该类,使用下面的方式:

char some = '5';
int lower = 5;
int upper = 12;
Filter ftr(some, lower, upper);

此时,实例化了一个类对象,可以通过引用filter来执行过滤行为:

vector<string> vtr;

……
ftr.filter(vtr);

还可以使用new关键字来实现:

char some = '5';
int lower = 5;
int upper = 12;
Filter *pfilter = new Filter(some, lower, upper);

此时,在堆上对该类的实例进行了空间的分配,返回了该Filter类的实例的指针pfilter,当需要执行过滤行为的时候,使用“->”来实现:

pfilter->filter(vtr);

因为使用了new关键字在堆上分配内存,在对象使用完成之后,需要手动进行释放:

delete pfilter;

这是必须要做的,否则会出现内存泄露,造成不必要的隐患。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值