classes, strings, learning in VS.NET

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • An Ony

    classes, strings, learning in VS.NET

    Hi,
    I'm just learning c++ with the book from Bjarne Stroustrup and I just type
    what is in his book into Visual Studio .NET. Is that a good compiler for
    that or not? I'm beginning to have my doubts... and it needs to be ANSI C++
    without the .NET framework.

    anyway, what's wrong with this:
    =============== ======>
    class Employee {
    short dept;
    public:
    Employee();
    };

    void main(){
    Employee e = Employee();
    }
    <============== ===
    I just put this in 1 file and build, VS complains:

    error LNK2001: unresolved external symbol "public: __thiscall
    Employee::Emplo yee(void)" (??0Employee@@$ $FQAE@XZ)
    fatal error LNK1120: 1 unresolved externals



    TIA


  • Christoph Rabel

    #2
    Re: classes, strings, learning in VS.NET

    An Ony wrote:

    Is that really your name? And your email address is invalid...
    [color=blue]
    > I'm just learning c++ with the book from Bjarne Stroustrup and I just type
    > what is in his book into Visual Studio .NET. Is that a good compiler for
    > that or not? I'm beginning to have my doubts... and it needs to be ANSI C++[/color]

    It is a good Compiler, at least the 2003 version.
    [color=blue]
    > anyway, what's wrong with this:
    > =============== ======>
    > class Employee {
    > short dept;
    > public:
    > Employee();[/color]

    Here you declare that you will provide a constructor for your Employee
    class.

    Later, the linker informs you that it couldnt find one. So either remove
    this line and the compiler generates a Constructor automatically for you
    or keep your promise and implement it:

    Employee::Emplo yee() {
    // Do whatever is useful here
    }
    [color=blue]
    > };
    >
    > void main(){[/color]

    int main() {

    void is not allowed for main.
    [color=blue]
    > Employee e = Employee();[/color]

    Looks weird. Why not simply:

    Employee e;
    [color=blue]
    > }[/color]

    Hope this helps,

    Christoph

    Comment

    • An Ony

      #3
      Re: classes, strings, learning in VS.NET

      > > I'm just learning c++ with the book from Bjarne Stroustrup and I just
      type[color=blue][color=green]
      > > what is in his book into Visual Studio .NET. Is that a good compiler for
      > > that or not? I'm beginning to have my doubts... and it needs to be ANSI[/color][/color]
      C++[color=blue]
      >
      > It is a good Compiler, at least the 2003 version.
      >[color=green]
      > > anyway, what's wrong with this:
      > > =============== ======>
      > > class Employee {
      > > short dept;
      > > public:
      > > Employee();[/color]
      >
      > Here you declare that you will provide a constructor for your Employee
      > class.
      >
      > Later, the linker informs you that it couldnt find one. So either remove
      > this line and the compiler generates a Constructor automatically for you
      > or keep your promise and implement it:
      >
      > Employee::Emplo yee() {
      > // Do whatever is useful here
      > }
      >[color=green]
      > > };
      > >
      > > void main(){[/color]
      >
      > int main() {
      >
      > void is not allowed for main.
      >[color=green]
      > > Employee e = Employee();[/color]
      >
      > Looks weird. Why not simply:
      >
      > Employee e;
      >[color=green]
      > > }[/color]
      >[/color]
      ah thanks, I'll go try it now. I'm used to program in Java so that's how I
      thought it was logic. And that book said, "don't declare without
      initialization" , so isn't "Employee e;" kinda wrong?


      Comment

      • An Ony

        #4
        Re: classes, strings, learning in VS.NET

        ok it works, thx!!

        now another problem:

        I've got a file X.cpp and an A.cpp and B.cpp
        X is the base class and class A and class B are derived from class X (class
        A: public X)
        so in A.cpp and B.cpp I write: #include "X.cpp"
        then in my main.cpp I write #include "A.cpp" and #include "B.cpp"
        and trouble strikes: X: class type redefinition



        Comment

        • Chris Theis

          #5
          Re: classes, strings, learning in VS.NET


          "An Ony" <nowhere@somewh ere.net> wrote in message
          news:bqhset$iho $1@gaudi2.UGent .be...[color=blue]
          > ok it works, thx!!
          >
          > now another problem:
          >
          > I've got a file X.cpp and an A.cpp and B.cpp
          > X is the base class and class A and class B are derived from class X[/color]
          (class[color=blue]
          > A: public X)
          > so in A.cpp and B.cpp I write: #include "X.cpp"
          > then in my main.cpp I write #include "A.cpp" and #include "B.cpp"
          > and trouble strikes: X: class type redefinition
          >[/color]

          Slow down :-) Include statements are for header files and should not be used
          for implementations (except templates but this is another story). So
          normally you would have a header files where you put all the class
          declarations and a .cpp file (or .cxx or .cc or whatever extension you
          prefer) where you put the implementation. Furthermore it's good practice to
          use "include guards" in your header file to prevent multiple inclusion.

          A short example:

          Header file MyClassA.h
          =============== =====

          class CMyClassA {
          public:
          CMyClassA();
          int GetData() const;

          protected:
          int m_Data;
          };

          Implementation file MyClassA.cpp:
          =============== ===============

          #include "MyClassA.h "

          CMyClassA()::CM yClassA()
          {
          m_Data = 0;
          }

          int CMyClassA::GetD ata() const
          {
          return m_Data;
          }

          HTH
          Chris


          Comment

          • Peter van Merkerk

            #6
            Re: classes, strings, learning in VS.NET

            > ok it works, thx!![color=blue]
            >
            > now another problem:
            >
            > I've got a file X.cpp and an A.cpp and B.cpp
            > X is the base class and class A and class B are derived from class X[/color]
            (class[color=blue]
            > A: public X)
            > so in A.cpp and B.cpp I write: #include "X.cpp"
            > then in my main.cpp I write #include "A.cpp" and #include "B.cpp"
            > and trouble strikes: X: class type redefinition[/color]

            I will discuss a technique to avoid redefinition errors at the end of
            this posting.

            But first of all you should not include .cpp files!

            Secondly, in C++ it is common to separate the class definition and the
            class implementation. Though the Java way of merging the class
            definition and implementation into one file is possible in C++, it is
            not recommended way of doing things.

            The class definition usually goes into a header file with a .h
            extension. In some environments a different extension is used for header
            files, but on VS the .h extension is the most common.

            A class definition looks something like this:

            --------- X.h ---------
            class X
            {
            public:
            virtual void foo();
            };

            The class implementation goes into the .cpp file. These files are
            officially called translation units. Translation units serve as input
            for C++ compiler. The compiler processes only one translation unit at a
            time. Even though your project (or makefile) may consist of many .cpp
            files, it is important to understand that the compilation process of the
            ..cpp files is completely independent from each other. The fact that .cpp
            files are compiled separately is nowadays hidden by modern IDE's,
            nevertheless it is still important to understand this aspect of the C++
            compilation process.

            If you want to use a class, derive from it or implement its member
            functions, the class definition (that what is stored in the .h file)
            must be known to the compiler.

            The class implementation file of the X class could look something like
            this:

            --------- X.cpp ---------
            #include "X.h"
            #include <iostream>

            void X::foo()
            {
            std::cout << "void X::foo() called" << std::endl;
            }

            The compiler does not need the class implementation to be able to call
            functions on that class or to derive from it. This is the reason why you
            should include .h files instead of .cpp files.

            Example:
            --------- main.cpp ---------
            #include "X.h"

            int main()
            {
            X x;
            x.foo();
            return 0;
            }

            When compiling the main.cpp file the preprocessor will substitute the
            line #include "X.h" with the contents of the X.h file. This way the
            compiler can "see" the definition of the X class when compiling the
            main.cpp file. When main.cpp is compiled, the compiled code goes into
            the main.obj, the compiled code references a X::foo() function, but at
            this stage that reference is not resolved. After the X.cpp file is
            compiled the compiled code for the X::foo() function can be found in the
            X.obj file. The linker puts the relevant code from main.obj and X.obj
            into the executable file and resolves the call main() makes to X::foo().

            (note that the linking process and .obj file extensions are VS specific
            and are beyond the scope of the C++ standard)

            To define a derived class the definition of the base class is also
            needed:

            --------- A.h ---------
            #include "X.h"
            class A : public X
            {
            public:
            virtual void foo();
            };

            The implementation file of class A only has to include A.h because the
            definition of class X will be include via the A.h file:

            --------- A.cpp ---------
            #include "A.h"
            #include <iostream>

            void A::foo()
            {
            std::cout << "void A::foo() called" << std::endl;
            }

            A common problem with include files is that directly or indirectly the
            include file is included twice within the same translation unit.
            Compilers don't like this because it means that they will see
            definitions twice or more; there you have your "redefiniti on error". For
            example in the example below X.h is included directly and indirectly via
            A.h

            --------- main.cpp ---------
            #include "X.h"
            #include "A.h"

            int main()
            {
            X x;
            x.foo();
            return 0;
            }

            A common solution for this problem is putting include guards in the .h
            files:

            --------- X.h ---------
            #ifndef X_H
            #define X_H

            class X
            {
            public:
            virtual void foo();
            };

            #endif

            When the X.h file is seen once inside a translation unit the next time
            it gets included it will skip the definitions and declarations inside
            the X.h file. Most experienced C++ programmers will always put include
            guards in header files, even when leaving those out would not cause
            redefinitions errors at that point in time.

            --
            Peter van Merkerk
            peter.van.merke rk(at)dse.nl





            Comment

            • Allan Bruce

              #7
              Re: classes, strings, learning in VS.NET

              [color=blue]
              > --------- main.cpp ---------
              > #include "X.h"
              > #include "A.h"
              >
              > int main()
              > {
              > X x;
              > x.foo();
              > return 0;
              > }
              >
              > A common solution for this problem is putting include guards in the .h
              > files:
              >
              > --------- X.h ---------
              > #ifndef X_H
              > #define X_H
              >
              > class X
              > {
              > public:
              > virtual void foo();
              > };
              >
              > #endif
              >
              > When the X.h file is seen once inside a translation unit the next time
              > it gets included it will skip the definitions and declarations inside
              > the X.h file. Most experienced C++ programmers will always put include
              > guards in header files, even when leaving those out would not cause
              > redefinitions errors at that point in time.
              >[/color]

              Since the OP is using VS, he could merely have
              #pragma once
              at the top of the headers, thus not needing to check #ifdef etc.


              Comment

              • Peter van Merkerk

                #8
                Re: classes, strings, learning in VS.NET

                > > --------- X.h ---------[color=blue][color=green]
                > > #ifndef X_H
                > > #define X_H
                > >
                > > class X
                > > {
                > > public:
                > > virtual void foo();
                > > };
                > >
                > > #endif
                > >
                > > When the X.h file is seen once inside a translation unit the next[/color][/color]
                time[color=blue][color=green]
                > > it gets included it will skip the definitions and declarations[/color][/color]
                inside[color=blue][color=green]
                > > the X.h file. Most experienced C++ programmers will always put[/color][/color]
                include[color=blue][color=green]
                > > guards in header files, even when leaving those out would not cause
                > > redefinitions errors at that point in time.[/color]
                >
                > Since the OP is using VS, he could merely have
                > #pragma once
                > at the top of the headers, thus not needing to check #ifdef etc.[/color]

                Since we are discussing standard C++ here, I prefer to stay as close to
                standard C++ as possible. The C++ standard does not specify what a
                compiler should do when it encounters #pragma once, other than ignoring
                it in case the compiler does not recognize it. Many compilers do not
                support this #pragma, and consequently putting #pragma once on top of
                the header will not result in the desired behaviour with those
                compilers. The solution I proposed should work on any reasonably
                conforming compiler.

                --
                Peter van Merkerk
                peter.van.merke rk(at)dse.nl


                Comment

                • Christoph Rabel

                  #9
                  Re: classes, strings, learning in VS.NET

                  Allan Bruce wrote:[color=blue]
                  > Since the OP is using VS, he could merely have
                  > #pragma once
                  > at the top of the headers, thus not needing to check #ifdef etc.[/color]

                  But the #ifdef is the normal and correct way to do this. The pragma you
                  stated is MS specific and only works with their compiler.

                  Dont you agree that its better to teach the OP to program in Standard
                  C++ than in a compiler specific dialect?

                  have a nice day,

                  Christoph

                  Comment

                  • Christoph Rabel

                    #10
                    Re: classes, strings, learning in VS.NET

                    An Ony wrote:[color=blue][color=green][color=darkred]
                    >>> Employee e = Employee();[/color]
                    >>
                    >>Looks weird. Why not simply:
                    >>
                    >>Employee e;
                    >>[color=darkred]
                    >>>}[/color]
                    >>[/color]
                    > ah thanks, I'll go try it now. I'm used to program in Java so that's how I[/color]

                    Yes, I already thought so and was tempted to ask you :)
                    [color=blue]
                    > thought it was logic. And that book said, "don't declare without
                    > initialization" , so isn't "Employee e;" kinda wrong?[/color]

                    This would be a definition without initialisation, not a declaration.
                    The difference between declaration and definition is rather important in
                    C++.

                    Nonetheless:

                    When you define a build-in type:

                    int i;

                    i has a random value. This can be very evil if you use this random value
                    afterwards.

                    Employee e;

                    Now, with classes its different. The constructor of e is always called
                    and it is responsible that the object is in a reliable state afterwards.
                    So, e is always initialized.
                    You are quite right, the above notation would be logical (and it is
                    allowed) but its far more too write ;-)

                    hth

                    Christoph

                    Comment

                    • Allan Bruce

                      #11
                      Re: classes, strings, learning in VS.NET


                      "Christoph Rabel" <odie@hal9000.v c-graz.ac.at> wrote in message
                      news:3fccb0e7$0 $18044$3b214f66 @aconews.univie .ac.at...[color=blue]
                      > An Ony wrote:[color=green][color=darkred]
                      > >>> Employee e = Employee();
                      > >>
                      > >>Looks weird. Why not simply:
                      > >>
                      > >>Employee e;
                      > >>
                      > >>>}
                      > >>[/color]
                      > > ah thanks, I'll go try it now. I'm used to program in Java so that's how[/color][/color]
                      I[color=blue]
                      >
                      > Yes, I already thought so and was tempted to ask you :)
                      >[color=green]
                      > > thought it was logic. And that book said, "don't declare without
                      > > initialization" , so isn't "Employee e;" kinda wrong?[/color]
                      >
                      > This would be a definition without initialisation, not a declaration.
                      > The difference between declaration and definition is rather important in
                      > C++.
                      >
                      > Nonetheless:
                      >
                      > When you define a build-in type:
                      >
                      > int i;
                      >
                      > i has a random value. This can be very evil if you use this random value
                      > afterwards.
                      >
                      > Employee e;
                      >
                      > Now, with classes its different. The constructor of e is always called
                      > and it is responsible that the object is in a reliable state afterwards.
                      > So, e is always initialized.
                      > You are quite right, the above notation would be logical (and it is
                      > allowed) but its far more too write ;-)
                      >
                      > hth
                      >
                      > Christoph[/color]

                      If you alternatively had

                      Employee *e;

                      then this is declared, but not initialised with the constructor until you
                      call

                      e = new Employee();

                      HTH
                      Allan


                      Comment

                      • Chris Theis

                        #12
                        Re: classes, strings, learning in VS.NET


                        "Allan Bruce" <allanmb@TAKEAW AYf2s.com> wrote in message
                        news:bqi6j4$d74 $1@news.freedom 2surf.net...[color=blue]
                        >[/color]
                        [SNIP][color=blue]
                        >
                        > Since the OP is using VS, he could merely have
                        > #pragma once
                        > at the top of the headers, thus not needing to check #ifdef etc.
                        >[/color]

                        This is certainly true. The advantage of #pragma once is that the compiler
                        does not need to scan the file completely and therefore you gain some speed.
                        But it's a compiler extension (AFAIK not a standard) and the canonical way
                        is still to use the include guards which are supported by every compiler &
                        also by C compilers.

                        Regards
                        Chris


                        Comment

                        • Jon Bell

                          #13
                          Re: classes, strings, learning in VS.NET

                          In article <bqhna1$grg$1@g audi2.UGent.be> ,
                          An Ony <nowhere@somewh ere.net> wrote:[color=blue]
                          >Hi,
                          >I'm just learning c++ with the book from Bjarne Stroustrup and I just type
                          >what is in his book into Visual Studio .NET.[/color]

                          [snip]
                          [color=blue]
                          >void main(){[/color]

                          Just out of curiosity, where does Bjarne Stroustrup use (or advise you to
                          use) void main()?

                          --
                          Jon Bell <jtbellap8@pres by.edu> Presbyterian College
                          Dept. of Physics and Computer Science Clinton, South Carolina USA

                          Comment

                          • Christoph Rabel

                            #14
                            Re: classes, strings, learning in VS.NET

                            Allan Bruce wrote:[color=blue]
                            > If you alternatively had
                            >
                            > Employee *e;
                            >
                            > then this is declared, but not initialised with the constructor until you[/color]

                            No it is a definition of a pointer to Employee without
                            initialisation. It is not a declaration.


                            e.g.

                            extern int i;

                            is a declaration.


                            Regards,

                            Christoph

                            Comment

                            • An Ony

                              #15
                              Re: classes, strings, learning in VS.NET

                              > Allan Bruce wrote:[color=blue][color=green]
                              > > Since the OP is using VS, he could merely have
                              > > #pragma once
                              > > at the top of the headers, thus not needing to check #ifdef etc.[/color]
                              >
                              > But the #ifdef is the normal and correct way to do this. The pragma you
                              > stated is MS specific and only works with their compiler.
                              >
                              > Dont you agree that its better to teach the OP to program in Standard
                              > C++ than in a compiler specific dialect?
                              >[/color]

                              indeed :)


                              Comment

                              Working...