1

我有一个包含许多简单类类型成员的类。更重要的是,随着我的发展,他们的数量正在增长。

我需要能够一次将它们全部重置,并且我想在不复制粘贴的情况下进行操作。代码目前看起来像:

typedef auto_ptr<odbc::PreparedStatement> Stmt;

class DbProxy {
private:
  void reset();

  Stmt a;
  Stmt b;
  Stmt c;
  // ... about 10 more
};

void DbProxy::reset()
{
  a.reset();
  b.reset();
  c.reset();
  // etc.
}

显然,我不喜欢将每个新成员都添加到reset()函数中(只是因为忘记了一个而出现了段错误)。

我打算做的是将它们全部收集到一个结构中,并将这个结构分配到auto_ptr. 所以代码看起来像这样:

typedef auto_ptr<odbc::PreparedStatement> Stmt;

class DbProxy {
public:
  DbProxy(): stmts(new OdbcResources) {}
private:
  void reset() { stmts.reset(); }

  struct OdbcResources {
    Stmt a;
    Stmt b;
    Stmt c;
    // ... about 10 more
  };
  auto_ptr<OdbcResources> stmts;
};

DbProxy 的对象不打算被复制或复制构造,尽管我没有费心通过将赋值和复制ctor 设为私有来确保这一点。

你觉得这种方法有什么问题吗?您还有其他建议吗?

编辑

根据@DeadMG 的建议,这个怎么样:

class DbProxy {
public:
  DbProxy();
private:
  enum Statements { SELECT1, SELECT2, INSERT, LAST };  // never mind the names

  void reset() { for (int i=0; i < LAST; i++) statement[i].reset(); }

  Stmt statements[LAST];
};
4

5 回答 5

3

使用静态大小的数组。

Stmt statements[10];

for(int i = 0; i < sizeof(statements) / sizeof(Stmt); i++)
    statements[i].reset();
于 2011-01-10T16:21:34.127 回答
2

不需要额外的auto_ptr(每个Stmt都是一个auto_ptr),如果您将它们收集在一个班级中,您可以通过简单的作业重新设置它们。与数组解决方案不同,您仍然保留它们有意义的名称。

请注意,您不能使用未命名的临时(例如stmts = OdbcResources();),因为生成的复制分配运算符将采用非const引用,因为成员(auto_ptr)不能从非const auto_ptrs 分配。

class DbProxy {
public:
  DbProxy() : stmts() {}
private:
  void reset() { OdbcResources tmp; stmts = tmp; }

  struct OdbcResources {
    Stmt a;
    Stmt b;
    Stmt c;
    // ... about 10 more
  };
  OdbcResources stmts;
};
于 2011-01-10T17:35:23.143 回答
1

这需要一个容器 - 假设odbc::PreparedStatement是可复制的,只需在其中包含这些向量DbProxy

class DbProxy {
private:
  void reset() { resources.clear(); } // all vanish!

  vector<odbc::PreparedStatement> resources;
};

别的,shared_ptr

typedef shared_ptr<odbc::PreparedStatement> Stmt;
class DbProxy {
private:
  void reset() { resources.clear(); } // all vanish!

  vector<Stmt> resources;
};
于 2011-01-10T16:27:31.863 回答
1

我认为这种方法没有任何问题。这看起来像“私有实现”的成语。你可以对细节感兴趣。

my2c

于 2011-01-10T16:35:04.907 回答
0

您也许可以简单地复制默认副本:

void reset() { *this = DbProxy(); }
于 2011-01-10T16:28:55.130 回答