首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何扩展编译器生成的复制构造函数

如何扩展编译器生成的复制构造函数
EN

Stack Overflow用户
提问于 2011-02-01 00:51:48
回答 4查看 2.1K关注 0票数 21

我经常遇到这样的问题,那就是我必须扩展一个编译器生成的复制构造函数。示例:

代码语言:javascript
复制
class xyz;
class C
{
    ...
    int a, b, c; 
    std::set<int> mySet;
    xyz *some_private_ptr;
};

假设只在特定条件下复制some_private_ptr。对于其他情况,应将其重置为NULL on copy。因此,我必须编写一个复制构造函数,如下所示:

代码语言:javascript
复制
C::C(const C &other) : 
     a(other.a), 
     b(other.b), 
     c(other.c), 
    mySet(other.mySet)
{      
   if(CanCopy(other.some_private_ptr)) // matches condition
      some_private_ptr = other.some_private_ptr;
   else
      some_private_ptr = NULL;
}

问题是类可能有许多数据成员,并且我很可能在添加数据成员时忘记更新复制构造函数。如果我能写作,那就太好了。

代码语言:javascript
复制
C::C(const C &other) :
   C::default_copy(other)
{      
   if(CanCopy(other.some_private_ptr)) // matches condition
      some_private_ptr = other.some_private_ptr;
   else
      some_private_ptr = NULL;
}

这将使我的代码更安全,更容易维护。不幸的是,我不知道有这样的可能性。有吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-01 00:57:27

当您定义自己的复制ctor时,编译器不会费心为您生成复制ctor。不幸的是,这意味着你必须自己做所有的腿工作!您可以将成员分组到类中的某种impl_结构中,然后依赖于复制ctor。

例如:

代码语言:javascript
复制
class xyz;
class C
{
  struct impl_
  {
    int a, b, c; 
    std::set<int> mySet;
    xyz *some_private_ptr;
  };

  impl_ data;
};

现在在你的拷贝服务器中

代码语言:javascript
复制
C::C(const C &other) : data(other.data)
{
 // specific stuff...      
}
票数 17
EN

Stack Overflow用户

发布于 2011-02-01 01:02:28

最简单的方法是引入一个基类:

代码语言:javascript
复制
class xyz;

struct CDetail {
  //...
  int a, b, c; 
  std::set<int> mySet;
  xyz *some_private_ptr;
};

struct C : private CDetail {
  C(C const &other)
  : CDetail(other)
  {
    if (!CanCopy(other.some_private_ptr))
      some_private_ptr = 0;
    // opposite case already handled
  }
};

在某种程度上,这是对继承的滥用,但是相对于嵌套的"impl“类的优点是: 1)您可以以”without affecting other members“而不是"data.name”的身份访问每个成员(在重构时减少代码更改);2)您可以将单个成员“提升”为受保护的或公共的impl

代码语言:javascript
复制
struct C : private CDetail {
protected:
  using CDetail::a;
};

struct D : C {
  void f() {
    cout << a;
  }
};

int main() {
  D d;
  d.f();  // D can access 'a'
  cout << d.a;  // main cannot access 'a'
  return 0;
}
票数 18
EN

Stack Overflow用户

发布于 2011-09-01 01:48:44

我要说的是创建一个处理复制的智能指针,然后将其用作类的成员。这些代码可能会给你一个概念:

根据基调用构造函数的初始化方式,将以相同的方式调用成员的构造函数。例如,让我们从以下内容开始:

代码语言:javascript
复制
struct ABC{
    int a;
    ABC() : a(0)    {   printf("Default Constructor Called %d\n", a);   };

    ABC(ABC  & other )  
    {
        a=other.a;
        printf("Copy constructor Called %d \n" , a ) ;
    };
};

struct ABCDaddy{
    ABC abcchild;
};

您可以执行以下测试:

代码语言:javascript
复制
printf("\n\nTest two, where ABC is a member of another structure\n" );
ABCDaddy aD;
aD.abcchild.a=2;

printf( "\n Test: ABCDaddy bD=aD;  \n" );
ABCDaddy bD=aD; // Does call the copy constructor of the members of the structure ABCDaddy ( ie. the copy constructor of ABC is  called)

printf( "\n Test: ABCDaddy cD(aD); \n" );
ABCDaddy cD(aD);    // Does call the copy constructor of the members of the structure ABCDaddy ( ie. the copy constructor of ABC is  called)

printf( "\n Test: ABCDaddy eD; eD=aD;  \n" );
ABCDaddy eD;
eD=aD;          // Does NOT call the copy constructor of the members of the structure ABCDaddy ( ie. the copy constructor of ABC is not called)

输出:

代码语言:javascript
复制
Default Constructor Called 0

Test: ABCDaddy bD=aD;
Copy constructor Called 2

Test: ABCDaddy cD(aD);
Copy constructor Called 2

Test: ABCDaddy eD; eD=aD;
Default Constructor Called 0

好好享受吧。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4853611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档