Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 替代复制粘贴编程的函数_C++ - Fatal编程技术网

C++ 替代复制粘贴编程的函数

C++ 替代复制粘贴编程的函数,c++,C++,我有一个对象,这个对象中的每个成员变量都有一个名称,我可以通过调用get_name()来获取它,我要做的是按照字母顺序连接所有成员变量的名称,然后做一些事情。例如: class CXMLWrapper<class T> { public: CXMLWrapper(const char* p_name) : m_local_name(p_name) { } //skip the get_name(), set_name() and others

我有一个对象,这个对象中的每个成员变量都有一个名称,我可以通过调用get_name()来获取它,我要做的是按照字母顺序连接所有成员变量的名称,然后做一些事情。例如:

class CXMLWrapper<class T>
{
public:
    CXMLWrapper(const char* p_name) : m_local_name(p_name)
    {
    }
    //skip the get_name(), set_name() and others    
private:
    string m_local_name;
    T m_type_var;
}
class object
{
public:
    object() : m_team("team"), m_base("base")
    {
    }
public:
    CXMLWrapper<string> m_team;
    CXMLWrapper<string> m_base;
...
}
我需要一个函数来完成这项工作,而不是在对象发生变化时复制和粘贴。有人有想法吗?

这看起来像是一个“观察模式”,您只需要在对象中保留一个副本作为成员变量“string name_;”,并将name_u的引用传递到CXMLWrapper,如下所示:

object o;
string sign = o.m_base.get_name();
sign += o.m_team.get_name();
class CXMLWrapper<class T>
{
public:
    CXMLWrapper(const string &name)
        : local_name_(name)
        {
        }
    //skip the get_name() set_name()    
    private:
        const string &local_name_;
}

class object
{
public:
    object()
        : team_("team"), 
          base_("base"),
          m_team(team_)
        , m_base(base_)
        {
        }
public:
    string team_;
    string base_;
    CXMLWrapper<string> m_team;
    CXMLWrapper<string> m_base;
}
类CXMLWrapper { 公众: CXMLWrapper(常量字符串和名称) :本地名称(名称) { } //跳过get_name()set_name()命令 私人: 常量字符串和本地名称; } 类对象 { 公众: 对象() :团队("团队),, 基地("基地"),, m_团队(团队u) ,m_base(base_) { } 公众: 弦乐队; 串基; CXMLM_团队; CXMLM_基地; }
如果具有名称的变量具有相同的类型(或这些类型属于一个层次结构),则可以使用这些变量的映射。这不是个好办法,但也许对你有帮助

范例

class object
{
public:
    object() //: m_team("team"), m_base("base")
    {
       this->vars["m_team"] = CXMLWrapper<string>("team");
       //.....
    }
public:
    map<string, CXMLWrapper<string> > vars;
    /*CXMLWrapper<string> m_team;
    CXMLWrapper<string> m_base;*/
...
}

object o;
string sign;
for(auto& x : o.vars)//i cannot remember syntax of for of map
    sign += x.get_name;
类对象
{
公众:
object()/:m_团队(“团队”),m_基地(“基地”)
{
这->vars[“m_团队”]=CXMLWrapper(“团队”);
//.....
}
公众:
地图变量;
/*CXMLM_团队;
CXMLM_基地*/
...
}
对象o;
字符串符号;
for(auto&x:o.vars)//我记不起映射的语法
符号+=x。获取名称;

对不起,我的写作错误。英语不是我的母语。

一种方法是使用外部成员名称库,CXMLWrapper类将更新该库:-

class BaseXMLWrapper
{
public:
  void ListMembers (const char *parent)
  {
    // find "parent" in m_types
    // if found, output members of vector 
    // else output "type not found"
  }
protected:
  void RegisterInstance (const char *parent, const char *member)
  {
    // find 'parent' in m_types
    // if not found, create a new vector and add it to m_types
    // find 'member' in parent vector
    // if not found, add it
  }
private:
  static std::map <const std::string, std::vector <const std::string> >
    m_types;
};

class CXMLWrapper <class T, const char *parent> : BaseXMLWrapper
{
public:
  CXMLWrapper(const char* p_name) : m_local_name(p_name)
  {
    RegisterInstance (parent, p_name);
  }
  // you could override assignments, copy and move constructors to not call RegisterInstance
  //skip the get_name() set_name()    
private:
  m_local_name;
}

class object
{
public:
  object() : m_team("team"), m_base("base")
  {
  }
public:
  CXMLWrapper<string, "object"> m_team;
  CXMLWrapper<string, "object"> m_base;
  ...
};
类BaseXMLWrapper
{
公众:
无效列表成员(常量字符*父级)
{
//在m_类型中查找“父项”
//如果找到,则输出向量的成员
//else输出“找不到类型”
}
受保护的:
无效注册表状态(常量字符*父项,常量字符*成员)
{
//在m_类型中查找“父项”
//如果未找到,请创建一个新向量并将其添加到m_类型
//在父向量中查找“成员”
//如果找不到,请添加它
}
私人:
静态std::map
m_类型;
};
类CXMLWrapper:BaseXMLWrapper
{
公众:
CXMLWrapper(常量字符*p_名称):m_本地_名称(p_名称)
{
注册表状态(父项、p_名称);
}
//您可以重写赋值、复制和移动构造函数以不调用RegisterInstance
//跳过get_name()set_name()命令
私人:
m_本地_名称;
}
类对象
{
公众:
对象():m_团队(“团队”),m_基地(“基地”)
{
}
公众:
CXMLM_团队;
CXMLM_基地;
...
};

这会增加对象构造的开销,但是由于它只是一个构造函数开销,它可能不会对整个系统性能造成很大影响。

< P>在正常C++中这样做的一种方式,提供了所有成员属于同一类或来自某个基类的函数,将对函数使用可变数量的参数。下面是一个例子

#include <stdarg.h>
string concatenateNames(int numMembers, ...)
{
    string output;
    va_list args;
    va_start(args, numMembers);
    for(int i = 0; i < numMembers; i++)
    {
        MemberClass *pMember = va_arg(args, MemberClass*);
        output += pMember->get_name();
    }
    va_end(args);
    return output;
}

class Object
{
    public:
        MemberClass x;
        MemberClass y;
        MemberClass z;
};

int main()
{
    Object o;
    string sign = concatenateNames(3, &o.x, &o.y, &o.z);
}
#包括
字符串串联名称(整数个数,…)
{
字符串输出;
va_列表参数;
va_启动(args,numbers);
for(int i=0;iget_name();
}
va_端(args);
返回输出;
}
类对象
{
公众:
成员类别x;
成员类别y;
类z;
};
int main()
{
对象o;
字符串符号=串联名称(3,&o.x,&o.y,&o.z);
}

如果所有成员的类型都不同,您可以查看C++11x:的可变模板,但我似乎找不到其他方法。

您是否有具有不同成员变量的各种对象?也许您可以使用一些集合来实现这一点?也许是向量。例如:类对象{/*..*//vector some_vars/*../}/*../*../**/for(auto&it:o.some_vars{sign+=it.get_name;})或者dictionary/mapIt的函数少而反射多。有一些方法可以在C++中提供一定程度的反射,但是如果没有它,最好是。手动复制粘贴和排序让我很恶心。@Matthieu M.是的,我也写java代码。你的代码非常危险,在正常情况下不可用。您使用引用,因此无法分配
CXMLWrapper
obejct
。我在中未看到观察者模式there@JanHerrmann我看不出有什么危险,我也不清楚你说的“不能分配”是什么意思——你说的是三/五/零规则?@doctorlove
object a;对象b;a=b不编译<代码>对象*a=新对象();对象b(*a);删除一条编译但创建2个对旧a字符串成员的悬空引用。使用此代码将强制执行字符串类型编码。您可能也希望将成员变量作为实际成员变量,而不仅仅是按名称隐藏在映射中usage@Dark_Daiver感谢您的建议,但我无法更改对象的布局,因为这是传递给我的参数。感谢您的回答,但我无法修改“CXMLWrapper”的布局或层次结构。“BaseXMLWrapper”是个好主意!虽然这不是一个完美的解决方案,但它可以删除大量重复的代码。我可以使用一个向量来保存for循环中的字符串,并按字母顺序对它们进行排序,然后连接。谢谢