3

So I am new to c++ and I'm writing for a scientific application.

Data needs to be read in from a few input text files.

At the moment I am storing these input variables in an object. (lets call it inputObj).

Is it right that I have to pass this "inputObj" around all my objects now. It seems like it has just become a complicated version of global variables. So I think I may be missing the point of OOP.

I have created a g++ compilable small example of my program:

#include<iostream>

class InputObj{
// this is the class that gets all the data
public:
void getInputs() {
    a = 1;
    b = 2;
};
int a;
int b;
};

class ExtraSolver{
//some of the work may be done in here
public:
    void doSomething(InputObj* io) {
        eA = io->a;
        eB = io->b;
        int something2 = eA+eB;
        std::cout<<something2<<std::endl;
    };  
private:
    int eA;
    int eB;

};

class MainSolver{
// I have most things happening from here

public:
void start() {
    //get inputs;
    inputObj_ = new InputObj();
    inputObj_ -> getInputs();
    myA = inputObj_->a;
    myB = inputObj_->b;

    //do some solve:
    int something = myA*myB;

    //do some extrasolve
    extraSolver_ = new ExtraSolver();
    extraSolver_ -> doSomething(inputObj_);

};
private:
InputObj* inputObj_;
ExtraSolver* extraSolver_;
int myA;
int myB;


};


int main() {
MainSolver mainSolver;
mainSolver.start();
}

Summary of question: A lot of my objects need to use the same variables. Is my implementation the correct way of achieving this.

CptLightning
  • 555
  • 1
  • 8
  • 18
  • so do you want an explanation of how you current code works with respect to Object Oriented ? – MimiEAM Dec 19 '12 at 10:35
  • First question to ask yourself: does it need to be OOP, or does it just need to do what you wanted? – Jari Komppa Dec 19 '12 at 10:36
  • I can't see any major issue with this code. If anything, I'd move InputObj outside of MainSolver, and pass it as a variable. – laurent Dec 19 '12 at 10:36
  • Your question is not clear.You need to explain what you want to achieve through your program – stamhaney Dec 19 '12 at 10:37
  • It's all relative... If this is a small console app I would opt to drop all the oop stuff, however, if it's going to be a big project I would opt to have it the oop style... – Stormenet Dec 19 '12 at 10:39
  • @MimiEAM Yea I still haven't got the feel for passing objects around to each other, when it is essentially global variables im looking for. – CptLightning Dec 19 '12 at 10:48
  • @JariKomppa I am a student who opted to learn OOP and c++ while writing this code, just to increase my skillset – CptLightning Dec 19 '12 at 10:49
  • @stamhaney added summary at bottom – CptLightning Dec 19 '12 at 10:52

4 Answers4

5

Don't use classes when functions will do fine.

Don't use dynamic allocation using new when automatic storage will work fine.

Here's how you could write it:

#include<iostream>

struct inputs {
    int a;
    int b;
};

inputs getInputs() {
    return { 1, 2 };
}

void doSomething(inputs i) {
    int something2 = i.a + i.b;
    std::cout << something2 << std::endl;
}

int main() {
    //get inputs;
    inputs my_inputs = getInputs();

    //do some solve:
    int something = my_inputs.a * my_inputs.b;

    //do some extrasolve
    doSomething(my_inputs);
}

I'll recommend reading a good book: The Definitive C++ Book Guide and List

Community
  • 1
  • 1
Pubby
  • 51,882
  • 13
  • 139
  • 180
  • 1
    *Don't use classes when functions will do fine.* That sentence is one *a lot* of people can learn from. +1 –  Dec 19 '12 at 10:40
  • 1
    My understanding of the question is that the real application needs a much more complicated global object, where functions might not be sufficient anymore. Otherwise, I agree with the "use functions if sufficient" rule. – Zane Dec 19 '12 at 10:50
  • 1
    You can still have a struct that is passed around from function to function – thecoshman Dec 19 '12 at 10:53
2

my answer would be based off your comment

"Yea I still haven't got the feel for passing objects around to each other, when it is essentially global variables im looking for "

so this 'feel for passing object' will come with practice ^^, but i think it's important to remember some of the reasons why we have OO,

  • the goal (in it simplified version) is to modularise your code so as increase the reuse segment of code. you can create several InputObj without redefining or reassignig them each time
  • another goal is data hiding by encapsulation, sometimes we don't want a variable to get changed by another function, and we don't want to expose those variable globally to protect their internal state.

for instance, if a and b in your InputObj where global variable declared and initialized at the beginning of your code, can you be certain that there value doesn't get changed at any given time unless you want to ? for simple program yes.. but as your program scale so does the chances of your variable to get inadvertently changed (hence some random unexpected behavior) also there if you want the initial state of a and b to be preserved , you will have to do it yourself ( more temp global variables? )

  • you get more control over the flow of your code by adding level abstractions with classes/inheritances/operation overriding/polymorphisms/Abtract and interface and a bunch of other concepts that makes our life easier to build complex architectures.

now while many consider global variable to be evil, i think they are good and useful when used properly... otherwise is the best way to shoot yourself in the foot.

I hope this helped a bit to clear out that uneasy feeling for passing out objects :)

MimiEAM
  • 2,505
  • 1
  • 26
  • 28
1

Is using your approach good or not strongly depends on situation. If you need some high speed calculation you can't provide incapsulation methods for your InputObj class, though they are recommended, because it will strongly reduce speed of calculation. However there are two rules that your can follow to reduce bugs: 1) Carefully using 'const' keyword every time you really don't want your object to modify:

  void doSomething(InputObj * io) -> void doSomething(const InputObj * io)

2) Moving every action related with initial state of the object(in your case, as far as I can guess, your InputObj is loaded from file and thus without this file loading is useless) to constructor: Instead of:

InputObj() { }
void getInputs(String filename) {
    //reading a,b from file
};

use:

InputObj(String filename) {
    //reading a,b from file
};
Arsenii Fomin
  • 3,120
  • 3
  • 22
  • 42
-3

You are right that this way you have implemented global variables, but I would call your approach structured, and not complicated, as you encapsulate your global values in an object. This will make your program more maintainable, as global values are not spread all over the place.

You can make this even nicer by implementing the global object as a singleton (http://en.wikipedia.org/wiki/Singleton_pattern) thus ensuring there is only one global object.

Further, access the object through a static member or function. That way you don't need to pass it around as a variable, but any part of your program can easily access it.

You should be aware that a global object like this will e.g. not work well in a multithreaded application, but I understand that this not the case.

You should also be aware that there is a lot of discussions if you should use a singleton for this kind of stuff or not. Search SO or the net for "C++ singleton vs. global static object"

Zane
  • 926
  • 8
  • 21
  • 2
    There is no justification for the singleton anti-pattern here (or any where for that matter). – thecoshman Dec 19 '12 at 10:55
  • One downvote without comment, the other seems to be rather fundamentalistic on not using singletons. Hm. – Zane Dec 20 '12 at 10:29
  • find me a valid use case for singletons, whilst you're at it, I'll have a perpetual motion machine too – thecoshman Dec 21 '12 at 11:48
  • It is not "fundamentalistic" to ask for a legitimate use case for something. when you hear of a cool new way to do stuff, you should ask "but is there actually a reason to use it", rather than "is there a reason *not* to use it". As far as singletons go, I'm not aware of a single reason to use them. – jalf Dec 21 '12 at 11:54
  • Saying there is no such thing as a use-case for singletons is fundamentalistic - though it might be true. Coshman's second comment shows however on what level he discusses this, and SO is not meant for this kind of discussions. That said, read e.g. http://stackoverflow.com/questions/228164/on-design-patterns-when-to-use-the-singleton - and I do implement logging classes as singletons. And singletons are not a cool new thing either. – Zane Dec 21 '12 at 14:05