C++;设计模式:加载文件的多种方式 强>概要:通过构造函数/p>查找标准的C++文件设计模式
我有一个C++;设计模式:加载文件的多种方式 强>概要:通过构造函数/p>查找标准的C++文件设计模式,c++,oop,design-patterns,C++,Oop,Design Patterns,我有一个Base类,该类具有所有派生类都将使用的一些功能(例如derived_a,derived_B)。主要区别在于Derived_A和Derived_B重写load函数,构造函数使用该函数加载数据文件(load也可以在构造函数外部显式调用) 我遇到了一个意外的问题:构造函数调用的load函数将类视为Base类型,但当我使用默认构造函数并显式调用load函数时,虚拟函数表允许调用预期的load函数 这听起来像是一个典型的问题,但我想不出一种方法来解决(我最近用Python编程,我相信,由于弱类型
Base
类,该类具有所有派生类都将使用的一些功能(例如derived_a
,derived_B
)。主要区别在于Derived_A
和Derived_B
重写load
函数,构造函数使用该函数加载数据文件(load
也可以在构造函数外部显式调用)
我遇到了一个意外的问题:构造函数调用的load
函数将类视为Base
类型,但当我使用默认构造函数并显式调用load
函数时,虚拟函数表允许调用预期的load
函数
这听起来像是一个典型的问题,但我想不出一种方法来解决(我最近用Python编程,我相信,由于弱类型,Python总是会调用预期的函数)
同样,我希望Base::load
是纯虚拟/抽象的(只实例化派生类);但是,这不会编译(我相信,因为编译器看到将调用纯虚拟函数)
你能帮忙吗
输出:
#include <iostream>
#include <string>
class Base
{
public:
Base() {}
Base(std::string x)
{
load(x);
}
virtual void load(std::string x)
{
std::cout << "\tBase::load " << x << std::endl;
}
};
class Derived_A : public Base
{
public:
Derived_A() {}
Derived_A(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_A::load " << x << std::endl;
}
};
class Derived_B : public Base
{
public:
Derived_B() {}
Derived_B(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_B::load " << x << std::endl;
}
};
int main()
{
// simpler code, but it doesn't behave as I hoped
std::cout << "Loading w/ constructor:" << std::endl;
Base*der_a = new Derived_A(std::string("file_A"));
Base*der_b = new Derived_B(std::string("file_B"));
// this is what I want to do
std::cout << "Loading w/ function post construction:" << std::endl;
der_a = new Derived_A;
der_a->load( std::string("file_A") );
der_b = new Derived_B;
der_b->load( std::string("file_B") );
return 0;
}
与构造函数一起加载:基本::加载文件\u A
基本::加载文件\u B加载w/函数后期构造:
派生的\u A::加载文件\u A
派生的\u B::加载文件\u B
代码:
#include <iostream>
#include <string>
class Base
{
public:
Base() {}
Base(std::string x)
{
load(x);
}
virtual void load(std::string x)
{
std::cout << "\tBase::load " << x << std::endl;
}
};
class Derived_A : public Base
{
public:
Derived_A() {}
Derived_A(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_A::load " << x << std::endl;
}
};
class Derived_B : public Base
{
public:
Derived_B() {}
Derived_B(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_B::load " << x << std::endl;
}
};
int main()
{
// simpler code, but it doesn't behave as I hoped
std::cout << "Loading w/ constructor:" << std::endl;
Base*der_a = new Derived_A(std::string("file_A"));
Base*der_b = new Derived_B(std::string("file_B"));
// this is what I want to do
std::cout << "Loading w/ function post construction:" << std::endl;
der_a = new Derived_A;
der_a->load( std::string("file_A") );
der_b = new Derived_B;
der_b->load( std::string("file_B") );
return 0;
}
#包括
#包括
阶级基础
{
公众:
Base(){}
基本(标准::字符串x)
{
载荷(x);
}
虚拟空荷载(标准::字符串x)
{
STD::CUT C++中的行为是很好定义的,在这个场景中它是不有用的,因为当调用<代码>加载(STD::String) >从<代码> BAS::BASIC(STD::String)
时,类没有完全构建。
有两种直接的方法:
A
您可以使用调用load的容器类型(可能还保留字符串)。如果您需要保留实例(例如,它们可能有专门的错误信息),这可能更实用
类加载器
{
公众:
加载器(基本*常数p,常数标准::字符串和位置):d_基本(p)
{
此->d_基地->装载(位置);
}
私人:
std::唯一的ptrd_基;
私人:
加载器(常量加载器&)=删除;
加载器和运算符=(常量加载器-)=删除;
};
使用中:
std::cout << "Loading w/ Loader:\n";
Loader l_der_a(new Derived_A, "file_A");
Loader l_der_b(new Derived_B, "file_B");
std::cout << "Loading w/ Base::Load<T>():\n";
Derived_A::Load<Derived_A>("file_A");
Derived_B::Load<Derived_B>("file_B");
std::cout您可以查找。+1好的一点,这是python鼓励的。您知道我是否需要为每个子类编写命名构造函数吗?或者是否有一种方法可以编写一次以防止重复代码(它总是调用load
,然后可能调用一些其他函数)。您没有访问require文件的权限(尝试打开链接时出错)我最终使用了加载程序
模式。非常感谢!
std::cout << "Loading w/ Base::Load<T>():\n";
Derived_A::Load<Derived_A>("file_A");
Derived_B::Load<Derived_B>("file_B");