#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>//setw setpre.. setfill
#include <fstream>
#include <sstream>
#include<stdexcept>//抛出runtimeexcept
#include <utility>//标准库
#include <memory>//defines general utilities to manage dynamic memory:auto_ptr
using namespace std;
//读单词文件,并把它列出来
ifstream& open_file(ifstream &in,const string &file){
in.close();
in.clear();
in.open(file.c_str());
return in;
}
//static 问题???? 利用父类的构造函数进行子类构造函数的初始化 《---子类可以赋值但不能直接序列化初始化父类成员 C++实现链表 const static成员???
//类类型的成员在类中会不会自动调用默认构造函数初始化 内置的类型成员不会自动初始化!! cl /d1 reportAllClassLayout cl -d1reportSingleClassLayoutFoo test.cpp
class ALA{
protected: string name;//放在静态池中所以没有内存
//string nn;
public :
ALA(const string& na):name(na){}
virtual void processAdoption()=0;
};
class def_an:public ALA{
public :
//static string& setname(){return name;}
def_an(const string &na):ALA(na){}
virtual void processAdoption(){
cout<<"adopt noting"<<endl;
}
};
class pubbly:public ALA{
public :
//static string& setname(){return name;}
pubbly(const string &na):ALA(na){}
virtual void processAdoption(){
//cout<<name;
cout<<"adopt a pubbly"<<endl;
}
};
class kitten:public ALA{
public :
kitten(const string &na):ALA(na){}
virtual void processAdoption(){
cout<<"adopt kitten"<<endl;
}
};
class adoption{//一个方法类用来进行遍历文本和生成对象,并且对于对象进行操作的类 //其实这个也可以用来实现工厂模式 这样就可以扩展性很强的增加不同国家的动物的控制了。
private:
ALA *pa;
ALA * readALA(istringstream& s){
string word;
if(s>>word){//最后,到这一步才知道没有,设s的状态为假,才退出 用了if else可以消除最后一次的无意义word
if(word=="pubbly")
return new pubbly("pubbly_name");
else if(word=="kitten")
return new kitten("kitten_name");
else{
cout<<word<<"**"<<flush;//在一行的末尾没东西了,还读到一次,最后一次word没有值只有默认的空字符串;
return new def_an("def_an_name");
}
}
else
return NULL;
}
//int a;//列表初始化,默认值方式
public:
//adoption(int ab=4):a(ab),pa(NULL){}
void processAdoptions(istringstream& datasource){
while(datasource){
if(pa=readALA(datasource)){
auto_ptr<ALA> pa_auto(pa);//利用智能指针可以保证抛出时,内存不泄露 这个安全问题
pa_auto->processAdoption();
}
}
}
~adoption(){if(pa) delete pa;}
};
//我已经把它包装在adoption类中了。
ALA * readALA(istringstream& s){
string word;
if(s>>word){//最后,到这一步才知道没有,设s的状态为假,才退出 用了if else可以消除最后一次的无意义word
if(word=="pubbly")
return new pubbly("pubbly_name");
else if(word=="kitten")
return new kitten("kitten_name");
else{
cout<<word<<"**"<<flush;//在一行的末尾没东西了,还读到一次,最后一次word没有值只有默认的空字符串;
return new def_an("def_an_name");
}
}
else
return NULL;
}
void processAdoptions(istringstream& datasource){
ALA *pa;
while(datasource){
if(pa=readALA(datasource)){
pa->processAdoption();
delete pa;
}
}
}
int main(int argc, char **argv)
{
ifstream map_file;//文件的读
//ALA *A=new kitten("SFDSFF");
if(argc!=2)
throw runtime_error("wrong number of argument");
if(!open_file(map_file,argv[1])) throw runtime_error("wrong open of file");
string word,line;
adoption* adostream=new adoption();//new 是真正调用构造函数方式,在堆上建 调用默认构造函数
//adoption adostream; //使用默认实参时自写名字就行。 如果有参数的情况下才用(parma1 parma2....)adoption adostream();是错误的主要是
//cout<<adostream.a; //因为其形式是编译器把它当成函数声明。所以只能用adoption adostream来调用默认构造函数 提供所有实参的构造函数也定义了默认构造函数
while(getline(map_file,line)){
istringstream stream(line);//因为要用到字符串的性质:如一个单词一个单词进行读,所以要利用字符串流进行处理
adostream->processAdoptions(stream);
// while(stream>>word) cout<<word<<" ";//word 的string以空格为结尾。
cout<<endl;
}
//cout<<sizeof(adoption);//为了验证:static变量不是存放在对象中,所以它是不具备占用对象内存的。
delete adostream;
return 0;
}