C++ class templates in XCode (10.5)

Discussion in 'Mac Programming' started by Sean7512, Feb 2, 2008.

  1. macrumors 6502a

    Joined:
    Jun 8, 2005
    #1
    Hello all, I have a quick question about XCode. I am working on my Data Structures homework, which was to create a class template with some functions in C++, and then to test the template with both a float and a struct (that we made in class). I have finished the assignment, but I am unable to compile it. So I was wondering, how should my files be in my XCode project? I know in Visual Studio you are not to include the class implementation file into the project. I have tried both ways, and continue to get errors (all of which occur in the class implementation file). So, I am certain that I am not setting this up correctly.

    If it helps, I can compress the folder to post here or I can just post my 3 source files (1 header, and 2 .cpp's), just let me know.

    Thanks in advance!!!

    Sean

    Edit:
    Silly me, I forgot to post the error that I get...
    In the class implementation file, above each function definition there is the "template<class DataType>" line, and that is where the error occurs for all of the class definitions, and the error is "Expected initializer before '<' token"
     
  2. macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
  3. thread starter macrumors 6502a

    Joined:
    Jun 8, 2005
    #3
    Well, since I do not get any errors in my header or my code with main() in it, I will just post the class implementation file for now...

    Hope that may help! As you can see, it is a VERY small exercise from our book, haha.

    Edit: It would probably make sense to post my header file for the class, hang on, I'll add it
     

    Attached Files:

  4. macrumors member

    Joined:
    Jan 27, 2008
    #4
    Code:
    template<class DataType>
    class Rectangle
    {
    public:
    	void setWidth(DataType someWidth);
    	void setLength(DataType someLength);
    	bool lengthGreaterThanWidth();
    	DataType getPerimeter();
    	DataType getArea();
    	
    private:
    	DataType width;
    	DataType length;
    	DataType perimeter;
    	DataType area;
    }; <-- pretty sure you need to add the semicolon there
    - Just another noobie here trying to be helpful :)
     
  5. macrumors newbie

    Joined:
    Feb 2, 2008
    #5
    Try this:

     
  6. thread starter macrumors 6502a

    Joined:
    Jun 8, 2005
    #6
    Ahh, stupid me! I am not sure how I missed that! Thanks a bunch, it now works fine!

    If anyone is wondering that doesn't know, when working with class templates in XCode, you have to have the class implementation file in the project folder BUT not included in your XCode project. It is the same way in Visual Studio as well.
     
  7. macrumors 68000

    Soulstorm

    Joined:
    Feb 1, 2005
    #7
    Actually, the way you have it set up will not work. And if it does, it will cause you problems later.

    You tend to disobey the rules of implementing header files in your computer. Both template definitions and implementations must exist in the same file, that means that you must write in the header files both the implementation and definition of the template. It won't work otherwise. And that happens only with the templates and it is just a thing with them, you have to accept it. That's your first mistake, right there.

    Your second mistake is the inclusion of the implementation file in your header file. When you include a header file, the compiler will include it in the project, and will also search for any implementation files in the project. If not found, only the header file is included. If you include the implementation file in your header file, you will come across errors of multiple definitions and implementations.

    My suggestions:
    1) Write any templates in the same files, do not use separate files for each, as you will later need to use workarounds that will definitely result in errors that may seem irrelevant to this, but will have this as the cause of the problem.
    2) Do not include any .cpp file in an .h file. Ever. Only include .h files in each file, and the compiler will handle the rest.
    3)Use the compiler preprocessor with #ifdef, #ifndef, #define. If you don't know how to use those, it's time to learn.

    I am saying all this, because I made the same mistakes at some point, and I spent entire days trying to figure out what was wrong.

    I hope I helped.
     
  8. thread starter macrumors 6502a

    Joined:
    Jun 8, 2005
    #8
    I wrote my files exactly the way that our book says to. The book AND teacher said that for a class template file, you MUST include the .cpp file at the END of the .h file. I am just going by what the teacher tells me or I lose points. It does work fine, so I did something right. For a normal class, ya, you include all files in your project and in the .cpp you include he .h and you don't include the .cpp in the header. The book goes into a lengthy explanation on why this won't work for a class template.

    Anyways, I appreciate your input, but I am going by the book, because I don't want to lose points :)

    Edit:
    Later tonight, when I have time, I will copy in exactly what my text book says on the matter. Maybe we can turn this into a discussion? haha BTW, my book for class is this one http://www.amazon.com/C-Classes-Structures-Jeffrey-Childs/dp/0131580515
     
  9. macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #9
    The way you (Sean7512) have the files set up will work, but it is wacky.

    Like SS says, for template classes, the implementation must be part of the header file. Your project accomplishes that by the #include "<the implementation file>"

    I think it's fine to split the template class declaration and implementation into two separate files.

    The problem, is that the implementation file has a .cpp extension. However it is not a .cpp file. It is actually an extension of the template declaration header file--that is, it is a header file itself. That is why you can't add it to the project--it can't be compiled as a real .cpp file.

    What people do in the real world in this situation is to name the files something like this:

    RectangleT.h (the Rectangle template declaration)
    RectangleTImpl.h (the Rectangle template implementation)

    Where RectangleT.h includes RectangleTImpl.h.

    The included implementation file has the correct .h extension, and the Impl suffix makes it clear that it contains the implementation of Rectangle. Different people use different suffixes or extensions for the implementation file, but the point is to not use .cpp, which means something else.

    Anyway, this is all moot. If I were you, I too would use the method your professor prefers... but only as long as that class lasts.
     
  10. macrumors 68000

    Soulstorm

    Joined:
    Feb 1, 2005
    #10
    I see. Well, as you may learn when progressing deeper into programming concepts, when programming is the main theme for discussion, not every professor knows what he's talking about. Probably, the professor just bought the book, studied only from that, and thinks this is the best way of programming.

    I would do what my professor says. However, I would abandon that coding style afterwards. As with your book, I have also a lengthy explanation of why you shouldn't write things this way, but all my explanations involve terms and concepts I think you are not ready to dive into yet.

    So, just do this: Follow your teacher to the letter. When this class ends, look into the internet, and read better on templates, compiler optimization methods and performance. And you will figure everything out.
     
  11. thread starter macrumors 6502a

    Joined:
    Jun 8, 2005
    #11
    Could you please tell me, the explanation? I am in my last semester of computer classes, and I have an internship with a company developing software for the military(C#), I am fairly certain that I am ready for the explanation, as our group of interns (4 people) have successfully finished two projects for the army that are actually being used in the field, which is a great feeling :)

    This assignment was a review, because we haven't took c++ since freshman year. Anyways, I told my teacher, and she said that she knows that its possible to do it other ways, but that the department head wants everything to be taught consistently so that the different teachers in the department are all on the same page when writing example programs, etc.

    Thanks a lot, everyone!
     
  12. macrumors 68000

    Soulstorm

    Joined:
    Feb 1, 2005
    #12
    OK:

    When you write at the preprocessor the "#include" directive, you actually tell the compiler to copy every text that this file includes, and paste it into the file in the place of the #include directive.

    If you place the #include directive for a .cpp file at the end of an .h file, you actually tell it to include the .cpp file, and paste it below the definition file. The teacher probably told you to do this as a workaround for the problem that exists with C++ templates that are not included automatically if not places entirely (both definition and implementation) inside the same file.

    Normally for a human, this is absolutely correct. However, the way most universal compilers are set to work, (like GCC) is: when you include an .h file the compiler also searches for a file with the same name but with another ending (.m, .cpp, .c, you name it) and actually pastes this files text into the header file, and pastes the newly created header file into the file you have written the #include directive. This happens when you have NOT written any #include directive to the end of a header file.

    As you can see, the thing you are doing while doing the thing I told you not to do ( :) ) is predefined and will normally be this way. So, problems may arise by only doing manually something that a compiler would normally do.

    But that is the least of your concerns.

    I suspect you know the #ifndef, #ifdef etc preprocessor commands. If you do, you would have known that the best use for them is to put them into the header file and not the implementation file. That way, when the compiler includes the file (using the method described above) it also verifies that this header file (and consequently, the implementation file) will not be included more than once (read about the one-definition-rule).

    But if you start including implementation files manually with the #include directive, this will result in multiple definitions or multiple implementations, as in larger projects, you will most likely forget including something. Not to mention that many compilers will complain about including directives that include both the implementation and header files, which will result in a disaster.

    As you can see, the method you want to use is not standard. And since it's not, you will deal with problems sooner or later.So, when dealing with templates, please write them all in a header file (.hh) and include only that.
     
  13. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #13
    The usual distinction is: .cpp = C++ source code, will be compiled and the compiled code included in the project. .h = header file, contains declarations, especially declarations used by users of the C++ file. And the C++ file usually includes a .h file with the same name as the very first thing.

    In this case, putting the template implementation into a file named .cpp just causes confusion. It won't be compiled and the compiled code included in the project. It doesn't include the .h file. It is included by the .h file. It contains C++ source code, but it isn't a C++ source file. Tools might get confused (for example an automated build system that thinks every .cpp file is a source file). Much better to call it something.impl.h or similar.
     

Share This Page