Pregunta

I have the following layout:

MainWindow  <--------- Settings
    \
     \
      V
   PerformOps

MainWindow takes in variables passed from Settings, and passes them on to PerformOps. If the Settings class is not used, MainWindow passed on defaults to PerformOps.

Currently I do:

class Settings{

public: 
   Settings(*parent);
   var1, var2, var3
   .
   .
   void exec();
}

class PerformOps{

public: 
   PerformOps();
   var1, var2, var3;
   .
   .
   void start();
}


class MainWindow{

private:
  Settings *set;    //share pointers over all methods
  PerformOps *op;

  bool settings_not_clicked = false;

  void saveChanges()
  {
     QSettings settings("my","app");
     settings.setValue("value1", op->var1);
     settings.setValue("value2", op->var2);
     settings.setValue("value3", op->var3);
  }

  void loadChanges()
  {
     QSettings settings("my","app");
     op->var1 = settings.value("value1");
     op->var2 = settings.value("value2");
     op->var3 = settings.value("value3");

  }

  void closeEvent(QCloseEvent *event)
  {
       event->ignore();
       saveChanges();
       event->accept();
  }

  void takeDataAndDoStuff()   //This is always called
  {
     op = new PerformOps;

     if(settings_not_clicked) {
        loadChanges()
     }
     else {
         op->var1 = 33;
         op->var2 = "Geronimo!";
         op->var3 = true;              
     }

     op->start();
  }


  void getStuff_maybe_if_clicked()   //This might not be always called
  {
     Settings *set = new Settings(this);
     set->exec()      //Pause parent, run Settings

     settings_not_clicked = false;
  }

Question: Is there a cleaner way to share data across classes without resorting to the dirty method of : op->var1 = set->var1;, taking into account that the set pointer might not always be initialised?

¿Fue útil?

Solución

Well, the approach itself is not that bad, however there are some things you can improve.

First of all, if I understood you correctly, you want to pass the settings if they exist, and pass the default values if they don't. In this case you can utilize the constructor:

class PerformOps
{
public:
    PerformOps( int v1 = 33, string v2 = "Geronimo!", bool v3 = true ): var1(v1), var2(v2), var3(v3)
    {
    }
    <...>
}

Now, if you call the constructor as PerformOps(), the default values will be set. If you call it and feed it some of the values, it will use them:

<...>
PerformOps *op;

if(settings_not_clicked) {
    op = new PerformOps( set->var1, set->var2, set->var3 );
}
else {
    op = new PerformOps();              
}
 <...>

of course, if you don't want to do it via the cunstructor, you could just make a function and call it like "setData()" and use the same technique with default function parameters.


Now, as for the pointers. It is a good idea to always initialize pointers with NULL, or nullptr if you have c++0x. Also, when you delete the memory, assign the pointer to NULL or nullptr again. This way you will be able to always see if the pointer is valid by a simple check.

someClass * ptr = nullptr;
<...>
ptr = new someClass();
<...>
delete ptr;
ptr = nullptr;

UPD

I would suggest you to get rid of your Settings class, and just use QSettings directly. You will not need to mess with the pointers, and reading/writing to QSettings is very fast.

Now, also don't forget that you can use QSettings from the heap:

QSettings * settings = new QSettings();

If you want each settings set to have a "parent", you could just derive your Settings class from QSettings, and just add one parent field into it. This will keep all the functionality of QSettings, which is very convenient.

Actually, your approach is fine too, all you need to do is just to check if the pointers are valid.

Otros consejos

Ok, so the problem is "I'm setting a pointer to a pointer that may or may not exist". In such a case Null Object pattern should help. This way you should be able getting rid of if-clause

Oh hang on. I just realized that I can use QSettings between classes (which is what SingerOfTheFall was clearly hinting at)

So from my Settings.cpp class I can do:

QSettings sett("my");
sett.begingroup("my_groupname");
sett.setValue("value1", var1);
sett.setValue("value2", var2);
sett.setValue("value3", var3);
sett.endGroup();

and I can retrieve this same information from ANY CLASS (duh!) by doing:

someRandomClass.cpp:

QSettings settings("my");
settings.beginGroup("my_groupname");
myvar1 = settings.value("value1");
myvar2 = settings.value("value2");
myvar3 = settings.value("value3");
settings.endGroup();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top