Configurations vs seters

I recently came across classes that use a configuration object instead of the usual configuration methods for configuration. A small example:

class A {  
   int a, b;  
public:  
   A(const AConfiguration& conf) { a = conf.a; b = conf.b; }  
};  

struct AConfiguration { int a, b; };

Enhancements:

  • You can expand your object and easily guarantee reasonable defaults for new values ​​if your users never know about it.
  • You can check the configuration for consistency (for example, your class only allows some combinations of values)
  • You save a lot of code by skipping setters.
  • You get a default constructor to specify the default constructor for your configuration structure and use A(const AConfiguration& conf = AConfiguration()).

Drawback (s):

  • You need to know the configuration at build time and not change it later.

, ? : ?

+5
5

, , , .

: , , , , , - , .

 A(const AConfiguration& conf) : a(conf.a), b(conf.b) {}

 A(int a_, int b_) : a(a_), b(b_) {}

. ( , , - ) .) ,

A a1(Configuration(42,42));
A a2 = Configuration(4711,4711);
A a3(7,7);

A urgh;
urgh.setA(13);
urgh.setB(13);

, . , - A.

+6

.

, struct , , "" "" , " " / "segfault" .

, , , . .

:

//version 1
struct AConfiguration { int version; int a; AConfiguration(): version(1) {} };
//version 2
struct AConfiguration { int version; int a, b; AConfiguration(): version(2) {} };

class A {  
   A(const AConfiguration& conf) {
     switch (conf.version){
       case 1: a = conf.a; b = 0;  // No access violation for old callers!
       break;
       case 2: a = conf.a; b = conf.b;  // New callers do have b member
       break;
     }
   }  
};  
+4

, A . , AConfiguration a b .

+2

.

( ), , , . ​​ , .

+1

.

, , .

struct AConfig1 { int a; int b; };
struct AConfig2 { int a; std::map<int,int> b; }

b, , :

class AConfig1 { public: int getA() const; int getB() const;  /* */ };
class AConfig2 { public: int getA() const; int getB(int key = 0) const; /* */ };

, .

, PIMPL.

namespace details { class AConfigurationImpl; }

class AConfiguration {
public:
  int getA() const;
  int getB() const;
private:
  AConfigurationImpl* m_impl;
};

, , .

, :

VISIDLE ( ).

, . AConfigurationImpl - , .

The more code means: constructor, copy constructor, assignment operator and destructor, which is a sufficient sum and, of course, getters and setters. Also note that these methods can no longer be inlined since their implementation is defined in the source file.

Regardless of whether it suits you, you decide.

0
source

All Articles