Thread: ...Classes...InGeneral...

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    40

    ...Classes...InGeneral...

    I just started reading about classes in my cpp book, and I have a few questions that will surely sound stupid to a few people, but, bear with me.

    Initially, I was declaring classes within main (data only), but then my book showed some examples, and they were all global (which I understand now, becuase they can't be local when they have member functions. A am correct is saying this, right? I assume that it is good protacol to always declare them globally?).

    So then I was asking myself, why not just declare all of the member functions within the class declaration itself? Isn't it easier to declare them in the class than to declare them outside and use the :: operator to tell the compiler which class they belong to?

    [/questions]
    thanks the help, greatly appreciated

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    You would define a class in the file scope so that all functions know that about it. If you declare it inside a function then only that function knows about that class.

    No as far as practice it all depends on what you want to do. If it makes sense to limit the class to one function the by all means define it inside that function.

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    >>why not just declare all of the member functions within the class declaration itself?

    This is possible. It's called inlining the functions. If the function definition is small/simple this works well. However, if the function is large/complex, then it becomes cumbersome, though my ability to explain why is inadequate. Also, when you start declaring classes in a header file, and then including the header file in your current project rather than writing the whole class in your current project, separating the class declaration from the method definitions by using a header file for the declaration and a cpp file for the definitions allows you to change the implementation of a process without (necessarily) changing the interface, so the user is unaware of the changes. Note that for templated classes, you have to put the definitions within the header file, either inside or outside the class declaration. For non-templated classes, it is considered better to separate the declaration from the definitions.

  4. #4
    Occasionally correct Mr.OC's Avatar
    Join Date
    Oct 2004
    Posts
    6
    Quote Originally Posted by elad
    It's called inlining the functions. If the function definition is small/simple this works well. However, if the function is large/complex, then it becomes cumbersome, though my ability to explain why is inadequate.
    In that case, I'll take a stab at it.

    The code in a function is copied into memory, and that copy is used when the function is called (throughout the entire life of the program). This is good for long, more complex functions.

    Inline functions are not copied into memory like non-inline functions are. Instead, when you call an inline function, it substitutes the function call for the code inside the function itself.

    When to use inline functions and non-inline functions? Well, since inline functions are substituted with the actual code, it can make your programs slower if the function is long. If the function is indeed long, it's best to use non-inline functions.

    That's a basic description of what happens.

    You probably won't notice a difference in speed, but it's just one of those things to know.

    It's also worth noting that you can use the inline keyword before the function name, for functions declared outside of the class. Example;

    Code:
    inline int getThing()
    {
        return something;
    }
    Last edited by Mr.OC; 12-03-2004 at 10:22 AM.

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Indeed; inlining the functions is something like using macros: The code is directly substituted for the function call.

    **DISCLAIMER: I am not 100% sure of the accuracy of the below paragraph.

    In addition to Mr. OC's comments about speed, if you have a huge long function, and it's inlined, then if you call the function 50 times in your code, then to the compiler it will be the equivalent of defining the function 50 times - and your executable size will probably skyrocket. I believe you'll also have problems if you have many objects of the same class: For every object of the class that you create, a whole separate set of the inlined functions has to be created. On the other hand, if it's not inlined then only one copy of the function is used, and it is shared between all objects and reused for each function call.

    **END DISCLAIMER**

    For small functions it's fine to inline them, and often you'll get a slight performance boost (i.e. 1 or 2 lines in the function) because you'll eliminate overhead from setting up the stack etc. yada yada that you hear about all the time. Just don't do it for more complex functions.

    Also, just to note: If you use the inline keyword, it acts only as a recommendation to the compiler to inline the function - the compiler can choose to ignore it, if it judges that inlining will have more of a negative effect than positive. This may also be the case for if you define functions inside the class declaration, though I'm not too sure (I've been told that it's the equivalent of using the inline keyword).
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I am not 100% sure of the accuracy of the below paragraph.
    It's accurate in that this is what would happen if a long function got inlined. But since, as you correctly note, inline is merely a suggestion, long functions simply won't ever get inlined.

    And you are also correct in thinking that defining functions in the class declaration is equivalent to defining them inline.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    40
    but it is impossible to declare a class within a function without inlining it then, right?
    Last edited by krygen; 12-03-2004 at 09:32 PM.

  8. #8
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    I think terms are being thrown around and the explantion is getting lost.
    inlining refers to a function that is declared with the inline keyword, which is a request for the compiler to insert the function's body in the function that called it.
    example:
    Code:
    inline void foo()
    {
      std::cout<<"Inside foo"<<std::endl;
    }
    Now when you define a class you can either give the member function definations inside the class defination or outside of it (ala another source file)
    Code:
    class Bar {
      public:
        Bar() { std::cout<<"Inside Bar constructor"<<std::endl; }
        void Boo() const;
    };
    
    void Bar::Boo() const {  std::cout<<"Boo"<<std::endl; }
    Now the class defination can be at any scope. So it is ok to put the defination inside a function with would then limit it to that scope.

  9. #9
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    You should put implementation classes, those that you use only in one module, at the top of the .cpp file or some sort of implentation .h file. That way if you need to change the interface to this implementation class your compiler will only compiler one file, which is better than being stuck compiling every file depending on the .h file. Putting classes inside of a function clutters the function body too much, I think.

  10. #10
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Expanding a bit on what okinrus said:

    When you make a modification to a file, any file that includes it must be recompiled along with the file itself. Now, when compiling, all your code needs to know about is signatures (that is, function signatures, and class declarations). It does not need to know anything else. So, at link time, the linker comes through, sees all of the calls to external functions, and matches them with functions that it finds in other compiled object files (if it finds no match, you get the dreaded and cryptic "Unresolved external" error). So, if you wish to change the imlpementation of a class but leave its interface intact, it is wise to have the declaration in the header file (which is included by other files, and contains all relevant signatures) and the implementation in the source file (which is included by nothing), so all that happens when you change the implementation is that a new object file is created, and your code is relinked instead of completely recompiled (or rather, just everything that depended on your class/functions being recompiled).

    Disclaimer: Do not take the above as too deep of an insight into the workings of compilers/linkers, but it is essentially correct, and goes a ways toward knowing how to keep compile times from getting out of hand.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Well, since inline functions are substituted with the actual code, it can make your programs slower if the function is long.

    no, the code itself is going to be the same size either way - the program runs *faster* because you've omitted all of the overhead of the function call.

    >> long functions simply won't ever get inlined.

    there are times when it's just not feasable to inline a function (ie: it's recursive, etc), but the size of the function isn't one of them.

    the bottom line is inlined functions increase speed and code size whereas called functions do just the opposite. at any rate, inline functions are mostly used where speed is absolutly critical (graphics code, tight processing loops, etc). most function won't fall in that category, though.

    @krygen: it's almost always better to separate the declaration from the definition.
    1) it makes browsing the interface easier.
    2) pre-compiling the implementation allows you to simply include the header and pass the .obj file to the linker when making new programs, which is much faster than recompiling the same code over and over.
    3) it reduces the dependancies when the class uses externally declared classes in it's implementation.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #12
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    There are other effects such as memory caching that could make inline functions bad in some cases. For a heavily inlined program, CPU memory accesses to retrieve the code are unlikely to be cached. But with functions, where only a small portion of memory is accessed often, these type of problems are unlikely to occur. I don't usually have that problem, though. More often I find inline functions increase compiling time. If an inline function in a .h file is changed, then every .cpp file that depends on the .h file must be recompiled, often signficantly increasing the compiler time.

  13. #13
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    I am not sure if this is what you are asking but classes do not need to be global you can just use them wherever you need them. As for the member functions that you can access using the :: operator that is just there more or less for readablity. This is how I handle classes.

    fakeclass.h
    Code:
    //header guards
    #ifndef fakeclass_h
    #define fakeclass_h
    
    class fake
    {
    
      public:
        void setxValue(int value);
        void setyValue(int value);
        void printxyValues();
        int getX();
        int getY();
      private:
        int x;
        int y;
    
    };
    
    #endif//fakeclass_h
    fakeclass.cpp
    Imagine putting all of this into the above class it would get pretty ugly even with this basic class.
    Code:
    #include <iostream>
    #include "fakeclass.h"
    
    int fake::getX()
    {
      
      return x;
      
    }
    
    int fake::getY()
    {
      
      return y;
      
    }
    
    void fake::printxyValues()
    {
      
      std::cout<<"x value equals: "<< x <<std::endl;
      std::cout<<"y value equals: "<< y <<std::endl;
      
    }
    
    void fake::setxValue(int value)
    {
      
      x = value;
      
    }     
        
    void fake::setyValue(int value)
    {
      
      y = value;
      
    }
    As for a class needing to be global the way you have to think about it is that is just a new datatype just like int, float,... they exist but unless you create one globally its only useable in the function you declare it in. say you might need a(for this case) fakeclass but only need it in fakeFunction not in main you just include fakeclass.h and then you can declare an instance of it.

    main.cpp
    Code:
    #include <iostream>
    #include "fakeclass.h"
    
    void fakeFunction()
    {
      
      //declare an instance of fake called random
      //that is local to fakeFunction
      fake random;
      
      random.setxValue(10);
      random.setyValue(20);
      
      std::cout<<"random's x value: "<<random.getX()<<std::endl;
      std::cout<<"random's y value: "<<random.getY()<<std::endl;
      
      random.printxyValues();
      
    }
    
    int main(void)
    {
          
      //main has no knowledge of random
      //but you could still use a different instance of fake
      fakeFunction();
      
      return 0;
      
    }
    Then ofcourse you could put all of this in on file but this is a simple class and even now it wouldn't be very "clean" looking. I hope this is what you were asking.
    Woop?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you Initialize all classes once with New?
    By peacerosetx in forum C++ Programming
    Replies: 12
    Last Post: 07-02-2008, 10:47 AM
  2. Multiple Inheritance - Size of Classes?
    By Zeusbwr in forum C++ Programming
    Replies: 10
    Last Post: 11-26-2004, 09:04 AM
  3. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  4. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM