![]() |
| | #1 |
| Registered User Join Date: Dec 2008
Posts: 13
| 1>library.obj : error LNK2005: "public: __thiscall Holding::Holding(char *,int)" (??0Holding@@QAE@PADH@Z) already defined in holding.obj And one like… 1>C:\...\c++\Polymorphism\Polymorphism Lab\Debug\Polymorphism Lab.exe : fatal error LNK1169: one or more multiply defined symbols found Any tips would be appreciated. ![]() My Main(): Code: // library.h
#ifndef _LIBRARY_H
#define _LIBRARY_H
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include "holding.h"
//cpp's taken out, what the hell was I thinking?
#include "book.h"
Holding *holdPtr[5];
Book *myBook;
#endif
//-------------------------CPP BELOW--------------------------------
// library.cpp
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "library.h"
ofstream csis;
int main(){
csis.open("csis.dat");
void getInfo(int);
for (int i=0;i<5;i++){
getInfo(i); }
for (int i=0;i<5;i++){
//cout holdPtr[i]->print();
holdPtr[i]->print(); }
csis.close();
}
void getInfo(int x){
char *titleTemp;
int callNumTemp;
char choice;
char *authorTemp;
cout << "Enter holdings type: " << endl;
cout << "/'b/' for book and /'r/' for recordings: ";
cin >> choice;
if (choice == 'b' || choice == 'B') {
cout << "Title: " << endl;
cin >> titleTemp;
cout << "Author: " << endl;
cin >> authorTemp;
cout << "CallNum: " << endl;
cin >> callNumTemp;
myBook = new Book(titleTemp,authorTemp,callNumTemp);
holdPtr[x] = myBook;
myBook->~Book();
} else
cout << "else called"<< endl;
}
Code: // holding.h
#ifndef _HOLDING_H
#define _HOLDING_H
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
class Holding{
protected:
char *title;
int titleLength;
int *callNumber; //*
public:
Holding(char*, int);
Holding();
virtual ~Holding();
virtual void print(/*ostream &*/) = 0;
};
#endif
//-------------------------CPP BELOW--------------------------------
// holding.cpp
#include "holding.h"
using namespace std;
extern ofstream csis;
Holding::Holding(char *tempTitle, int tempCallNumber){
titleLength = strlen(tempTitle);
title = new char[titleLength + 1];
strcpy(title, tempTitle);
title[titleLength] = '\0';
*callNumber = tempCallNumber;
}
Holding::~Holding(){
delete [] title;
}
Code: // Book.h
#ifndef _BOOK_H
#define _BOOK_H
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include "holding.h"
extern char *author; //NEW NEW
extern int authorLength;
class Book : public Holding {
protected:
//char *author;
//int authorLength;
public:
Book(char*, char*, int);
Book(const Book &);
~Book();
virtual void print(/*ostream &*/); //ostream is req for project
// but for the time being, ignoring to fix other problem.
};
#endif
//-------------------------CPP BELOW--------------------------------
// Book.cpp
#include "book.h"
using namespace std; //new
extern ofstream csis; //new
char *author; //NEW NEW
int authorLength;
Book::Book(char *title, char *tempAuthor, int callNumtemp) : Holding(title, *callNumber) {
authorLength = strlen(tempAuthor);
author = new char[authorLength + 1];
strcpy(author, tempAuthor);
author[authorLength] = '\0';
}
Book::~Book(){
delete [] author;
}
void Book::print(/*ostream &out*/){
cout << "Book: " << author << " " << '\"' << title << '\"' << " " << callNumber << endl;
csis << "Book: " << author << " " << '\"' << title << '\"' << " " << callNumber << endl; //uncommented
}
Last edited by Skyy; 12-06-2008 at 02:51 PM. |
| Skyy is offline | |
| | #2 | |
| The larch Join Date: May 2006
Posts: 3,082
| Don't include cpp files. Remember, cpp files are compiled, h files are included (pasted into cpp files). Also, the globals declared in "library.h" might need to be declared extern and then defined in one cpp file. Of course, having all these globals don't make for robust code - and code others will enjoy figuring out. For example, why is csis global if it is only used in main?
__________________ I might be wrong. Quote:
| |
| anon is offline | |
| | #3 |
| Registered User Join Date: Dec 2008
Posts: 13
| Thank you, Anon, for the quick reply. ![]() I fixed the first and third concerns, what was I thinking when including the cpp's?! Pardon my inexperience but I don't know what 'declared extern' means... |
| Skyy is offline | |
| | #4 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| It means something like this: Code: // X.cpp: int myint; // X.h: extern int myint; If you don't do it this way, you will get multiple globals of the same name and the linker will complain.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |
| Elysia is offline | |
| | #5 |
| Registered User Join Date: Dec 2008
Posts: 13
| Thanks Elysia, my code has been changed and first post reflects that change. Would it be wise to also declare Holding *holdPtr[5]; and Book *myBook; in library as extern? The program now starts but gives me warnings like "Run-Time Check Failure #3 - The variable 'titleTemp' is being used without being initialized." And then a forced break after inputting the title and pressing enter, "Unhandled exception at 0x6984653e (msvcp90d.dll) in Polymorphism Lab.exe: 0xC0000005: Access violation writing location 0xcccccccc." and opens is stream at line 1010 "_Ch = _Traits::to_char_type(_Meta); // got a character" I'll try to figuring it out and will post a little bit later but will check this thread if anyone has an tip to help me out with these erros. 'til then. |
| Skyy is offline | |
| | #6 | |
| The larch Join Date: May 2006
Posts: 3,082
| Code: char *titleTemp; ... cin >> titleTemp; Unless, you are required to do it this way (no strings, containers etc), good luck with debugging.
__________________ I might be wrong. Quote:
Last edited by anon; 12-06-2008 at 04:09 PM. | |
| anon is offline | |
| | #7 |
| and the Hat of Guessing Join Date: Nov 2007
Posts: 8,740
| The fun part about pointers is that they just point somewhere. Currently, your TitleTemp variable points to New Jersey. You want it to point to memory somewhere inside your computer. You could use new, like you've done elsewhere, but that's just wallpapering over the real problem -- the real problem is that you don't want char *, you want std::string. |
| tabstop is offline | |
| | #8 | ||
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| Quote:
Also, I missed it at first, but you may want to take a look at: http://cpwiki.sf.net/Don't_remove_parameter_names Also, set your warnings to maximum. Project properties -> C/C++ -> General -> Warnings (to Level 4). It provides valuable diagnostic output.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| ||
| Elysia is offline | |
| | #9 | |
| Registered User Join Date: Dec 2008
Posts: 13
| Good day. I've replaced: cout << "Title: " << endl; cin >> titleTemp; With: cout << "Title: " << endl; titleTemp = new char[20]; //numbers for testing, change later. cin.getline(titleTemp, 5); However, it now skips asking for the titleTemp input and assigns it '0', it does ask for the authorTemp which is identical and below the titleTemp lines above... I'm really struggling with getting the input to the constructor. @Elysia: Both recommendations applied, I don't see the edit botton on the original post so I can't change it. Thanks for the tips. @tabstop: Since my prof. did not teach us about it and the instructions requires destructors for each holding, I don't think I can use std::string. That being said, I did try it anyway (Googled it) and ran into errors. So I reverted back. Quote:
Last edited by Skyy; 12-07-2008 at 02:43 PM. | |
| Skyy is offline | |
| | #10 | ||
| The larch Join Date: May 2006
Posts: 3,082
| Quote:
Perhaps, since you are going to allocate memory for the input in Book too and copy it, you could use just a plain stack char array which is a bit larger than 20 characters.
__________________ I might be wrong. Quote:
| ||
| anon is offline | |
| | #11 | |||
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| You don't really need pointers at all. char string[50]; std::cin.getline(string, sizeof(string)); Or better std::string string; std::getline(std::cin, string); Quote:
Quote:
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |||
| Elysia is offline | |
| | #12 |
| Registered User Join Date: Dec 2008
Posts: 13
| Thanks for the quick replies, you guys rock. I tried it earlier using code similar to Elysia's first example, now I'm using a style similar to the second example but getting the same error both times: \library.cpp(59) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Book *' (or there is no acceptable conversion) \book.h(27): could be 'Book &Book: perator =(const Book &)'while trying to match the argument list '(Book, Book *)' From what I've read about this error, I seems to be related to incorrect variables sent to the constructors, am I calling the 'holding' and 'book' constructors correctly? Here is the related code. In main(): Code: cout << "Title: "; std::getline(std::cin, titleTemp); cout << endl << "Author: "; std::getline(std::cin, authorTemp); cout << endl << "CallNum: "; cin >> callNumTemp; Line 59: myBook[x] = new Book(titleTemp,authorTemp,callNumTemp); Code: class Book : public Holding {
protected:
std::string author;
int authorLength;
public:
Book(std::string titleTemp, std::string authorTemp, int callNumTemp);
~Book();};
***cpp***
Book::Book(std::string title, std::string tempAuthor, int callNumtemp) : Holding(title, *callNumber) {
author = tempAuthor;}
Code: class Holding{
protected:
std::string title;
int titleLength;
int *callNumber;
public:
Holding(/*char**/std::string titleTemp, int callNumTemp);
Holding();
****cpp***
Holding::Holding(std::string tempTitle, int callNumTemp){
title = tempTitle;
*callNumber = callNumTemp;
}
|
| Skyy is offline | |
| | #13 |
| and the Hat of Guessing Join Date: Nov 2007
Posts: 8,740
| new returns a pointer to a freshly constructed Book. You don't want that, since you have a perfectly good Book already hanging out there on the left side (I think -- I somehow missed how you defined your array there). Do you know how many Books there are supposed to be ahead of time? (If not, you could look into vector.) As it stands, you would presumably want to have some functions that could set the author, call number, etc. of a previously existing Book. |
| tabstop is offline | |
| | #14 | |
| The larch Join Date: May 2006
Posts: 3,082
| Well the assignment says that you need pointers and new since you will be creating two different types of Holdings. It doesn't say though that the array of pointers to holdings should be declared as global in a separate header. More likely you should just declare it in main() and getInfo should just return a new Holding (that is Book/Record) that you store in that array. There is also no need for the global myBook since it is not used for anything that has to live beyond a function call (and strangely I see you are also calling the destructor on the object through that that you have just allocated - don't do that) I don't see how using char* instead of string helps with the task at hand which is learning polymorphism. There is nothing polymorphic about char*, just an awful lot of tedious and repetitious work needed for anything (unless you write your own String class - but why should you?) You don't need a destructor in Holding to release char arrays, you need it because Holding is an abstract base class and you need a destructor that can be declared virtual. The body can be completely empty, but without this the destructor of Book won't get called if you later delete a ptrHolding and its members - again even if they are std::string's - won't be destroyed.
__________________ I might be wrong. Quote:
Last edited by anon; 12-08-2008 at 02:00 AM. | |
| anon is offline | |
| | #15 |
| Registered User Join Date: Dec 2008
Posts: 13
| Before I continue coding, am I on the right track now? I'm learning so much here, what a find. Code: // library.cpp
#include <sstream>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "library.h"
#include <string>
Book *getInfo();
using namespace std;
ofstream csis;
int main(){
csis.open("csis.dat");
Holding *holdPtr[5];
for (int i=0;i<5;i++){
/*holdPrt[i] = new Holding(); can't do that */
*holdPrt[i] = getInfo(); //need to figure out how to declare holdPrt
}
for (int i=0;i<5;i++){
holdPtr[i]->print();
}
csis.close();
}
Book *getInfo(){
int callNumTemp;
char choice;
std::string titleTemp;
std::string authorTemp;
cout << "Enter holdings type: " << endl;
cout << "/'b/' for book and /'r/' for recordings: ";
cin >> choice;
if (choice == 'b' || choice == 'B') {
cout << "Title: ";
std::getline(std::cin, titleTemp);
cout << endl << "Author: ";
std::getline(std::cin, authorTemp);
cout << endl << "CallNum: ";
cin >> callNumTemp;
Book *myBook;
myBook = new Book(titleTemp,authorTemp,callNumTemp);
return myBook;
} else
cout << "else called (testing)"<< endl;
return 0;
}
Last edited by Skyy; 12-08-2008 at 08:57 PM. |
| Skyy is offline | |
![]() |
| Tags |
| pholymorphism, pointers, virtual |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| template and polymorphism | lehe | C++ Programming | 7 | 06-22-2009 02:41 PM |
| Base-class pointer, accessing object from derived class | Korhedron | C++ Programming | 15 | 09-28-2008 05:30 AM |
| Smart pointer class | Elysia | C++ Programming | 63 | 11-03-2007 07:05 AM |
| Polymorphism Theory Question - Polymorphic Class Definition. | ventolin | C++ Programming | 3 | 10-31-2005 12:05 PM |
| polymorphism | slaveofthenet | C++ Programming | 15 | 07-10-2003 11:50 AM |