0
点赞
收藏
分享

微信扫一扫

谈谈Pytorch中的dataset

爱做梦的夏夏 03-11 13:00 阅读 2
组合模式

        组合模式又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构,以一致的方式处理叶子对象以及组合对象,不以层次高低定义类,都是结点类

       一、传统组合模式

        举例,大学、学院、系,它们之间不是继承关系,是组合关系:大学由学院组成,学院由系组成,但是它们都是组织结点,一个大学,n个学院,一个学院m个系,大学、学院是 组合类型的,它们都包含结点成员,系是 叶子类型 的,不包含结点成员

        把大学类、学院类、系类抽象为组织结点类,它们都是组织结点类的子类(其中大学子类、学院子类是组合类型的类,系是叶子类型的类),按照具体依赖抽象原则,以子类共有的属性和行为来定义结点类,代码如下:

//组织结点(基类)Organization
class Organization{                      //具体依赖抽象原则
	std::string name;//数据成员
public:
	Organization( std::string name):name(name) { }//构造函数
	virtual ~Organization(){ }                    //虚析构
	//其他成员函数
    virtual std::string getName(){ return name; }   
    virtual void add(Organization* o){ throw "叶子结点没有成员!\n"; }
    //virtual void remove( ){ throw "叶子结点没有成员!\n";  }
    virtual void print() = 0;  //
};    

        组合类型的子类University、College,重写基类成员函数,代码几乎一样

//组合类型(子类)University College
//University
class University:public Organization{
	std::list<Organization*> ul; //以基类的形式包含其他子类对象
public:
	University(std::string name):Organization(name) { }
	~University(){
		std:: cout << "~University\n";
		for(auto o:ul){ delete o; }		
	}
	//重写
	virtual void add(Organization* o){
		ul.push_back(o);
	}
    virtual void print(){
		std::cout << getName() << "\n";//基类成员获取,基类的成员也是子类的组成部分
		for( auto o:ul ){
			o->print();
		}
	}	
};

//College
class College:public Organization{
	std::list<Organization*> cl; //以基类的形式包含其他子类对象
public:
	College(std::string name):Organization(name) { }
	~College(){
		std:: cout << "~College\n";
		for(auto o:cl){ delete o; }		
	}
	//重写
	virtual void add(Organization* o){
		cl.push_back(o);
	}
    virtual void print(){
		std::cout << getName() << "\n";//基类成员获取,基类的成员也是子类的组成部分
		for( auto o:cl ){
			o->print();
		}
	}	
};

        叶子类型的子类(Department)

//叶子类型(子类)Department
class Department:public Organization{
public:
	Department(std::string name):Organization(name) { }
	~Department(){
		std:: cout << "~Department\n";
	}
	//重写
	virtual void print(){
		std::cout << getName() << "\n";
	}
};

        头文件及测试代码

#include <iostream>
#include <string>
#include <exception>
#include <list>

int main() 
{
	University u("清华大学");
	Organization* c1 = new College("计算机学院");
	Organization* c2 = new College("信息工程学院");
	Organization* d = new Department("信息工程");
	u.add( c1 );
	u.add( c2 );
	c2->add( d );
	u.print();
	//c2->print();	
    return 0;
}

        二、组合模式的结点设计

        把组合类型的的属性、行为都放到结点,以对象组是否为空来判断是叶子类型的还是组合类型的,这样叶子类型也可以扩展为组合类型,虽然看起来有点混乱,但是确实可行,比如系原来是叶子,现在有了个学生会,添加成员后就可以不是叶子了

#include <iostream>
#include <string>
#include <exception>
#include <list>
 
//组织结点(基类)Organization
class Organization{  //具体依赖抽象原则
	std::string name;//数据成员
	std::list<Organization*> ol; //对象组
public:
	Organization( std::string name):name(name) { } //构造函数
	virtual ~Organization(){	 //虚析构
		for(auto o:ol){ delete o; }	
	}                    
	//其他成员函数 
    virtual void add(Organization* o){ ol.push_back(o); }	
    virtual void print(){
		std::cout << name << "\n";
		if( !ol.empty() ) //判断是否是叶子结点
		{ 
			for( auto o:ol ){
				o->print();
			}
		}	
	}
};    
 
//University
class University:public Organization{
public:
	University(std::string name):Organization(name) { }
	~University(){ std:: cout << "~University\n"; }
};
 
//College
class College:public Organization{
	std::list<Organization*> cl; //以基类的形式包含其他子类对象
public:
	College(std::string name):Organization(name) { }
	~College(){
		std:: cout << "~College\n";
	}
};
 
//Department
class Department:public Organization{
public:
	Department(std::string name):Organization(name) { }
	~Department(){
		std:: cout << "~Department\n";
	}
};
 
//StudentUnion
class StudentUnion:public Organization{
public:
	StudentUnion(std::string name):Organization(name) { }
	~StudentUnion(){
		std:: cout << "~StudentUnion\n";
	}
};
 
int main() 
{
	University u("清华大学");
	Organization* c1 = new College("计算机学院");
	Organization* c2 = new College("信息工程学院");
	Organization* d1 = new Department("信息工程");
	Organization* d2 = new Department("软件工程");
	Organization* s = new StudentUnion("信息工程学生会");
	
	d1->add( s );
	c1->add( d2 );
	c2->add( d1 );
	
	u.add( c1 );
	u.add( c2 );
	
	u.print( );
	//c2->print( );	
    return 0;
}

        三、修改打印函数,打印出树形结构

         1、 修改print

    virtual void print( int depth ){
		for(int i=0; i< depth; ++i)
			std:: cout << "--";
		std::cout << name << "\n";
		if( !ol.empty() ) //判断是否是叶子结点
		{ 
			for( auto o:ol ){
				o->print(depth+1);
			}
		}	
	}

        2、调用修改为

u.print(0);
//c2->print( 0 );

举报

相关推荐

0 条评论