Hello people,

While compiling the code in set of files below, I get the following error:

Error	1	error C2653: 'Member' : is not a class or namespace name	c:\personal\nu\csc 300\project\library\library\book.h	50	

Error	2	error C2653: 'Member' : is not a class or namespace name	c:\personal\nu\csc 300\project\library\library\book.h	51

Here is the code:

Book.h:

#pragma once
#include "Member.h"

class Book
{
public:
	Book(
		char* _name,
		char* _title,
		char* _description,
		char* _author,
		char* _publisher,
		char* _publishDate,
		int _pages
	);
	~Book(void);
private:
	char* name;
	char* title;
	char* description;
	char* author;
	char* publisher;
	char* publishDate;
	int pages;
	
	char* status;       // in, out, usage
	char* usingGuest;   // Name of guest currently reading the book
	int checkOutMember; // Member ID who checked out this book
	char* checkOutDate;
	char* checkInDate;
public:
	char* getName(void);
	char* getTitle(void);
	char* getDescription(void);
	char* getAuthor(void);
	char* getPublisher(void);
	char* getPublishDate(void);
	int getPages(void);
	char* getStatus(void);
	char* getUsingGuest(void);
	int getCheckOutMember(void);
	char* getCheckOutDate(void);
	char* getCheckInDate(void);

	int read(char* _usingGuest);
private:
	int checkOut(int _checkOutMember, char* _checkOutDate);
	int checkIn(char* _checkInDate);

	friend int Member::checkOut();
	friend int Member::checkIn();
};

Book.cpp:

#include "Book.h"

Book::Book(
	char* _name,
	char* _title,
	char* _description,
	char* _author,
	char* _publisher,
	char* _publishDate,
	int _pages
)
{
	name = _name;
	title = _title;
	description = _description;
	author = _author;
	publisher = _publisher;
	publishDate = _publishDate;
	pages = _pages;
}

Book::~Book(void)
{
}

char* Book::getName(void)
{
	return name;
}

char* Book::getTitle(void)
{
	return title;
}

char* Book::getDescription(void)
{
	return description;
}

char* Book::getAuthor(void)
{
	return author;
}

char* Book::getPublisher(void)
{
	return publisher;
}

char* Book::getPublishDate(void)
{
	return publishDate;
}

int Book::getPages(void)
{
	return pages;
}

char* Book::getStatus(void)
{
	return status;
}

char* Book::getUsingGuest(void)
{
	return usingGuest;
}

int Book::getCheckOutMember(void)
{
	return checkOutMember;
}

char* Book::getCheckOutDate(void)
{
	return checkOutDate;
}

char* Book::getCheckInDate(void)
{
	return checkInDate;
}

int Book::read(char* _usingGuest)
{
	if(_usingGuest != ""){
		usingGuest = _usingGuest;
		status = "usage";

		return 1;
	}
	
	return 0;
}

int Book::checkOut(int _checkOutMember, char* _checkOutDate)
{
	if(_checkOutMember && _checkOutDate != ""){
		checkOutMember = _checkOutMember;
		checkOutDate = _checkOutDate;
		status = "out";

		return 1;
	}

	return 0;
}

int Book::checkIn(char* _checkInDate)
{
	if(_checkInDate != ""){
		_checkInDate = _checkInDate;
		status = "in";

		return 1;
	}

	return 0;
}

Guest.h:

#pragma once
#include "Book.h"

class Guest
{
public:
	Guest(char* _name);
	~Guest(void);
protected:
	char* name;
public:
	int read(Book &_book);
};

Guest.cpp:

#include "Guest.h"

Guest::Guest(char* _name)
{
	name = _name;
}

Guest::~Guest(void)
{
}

int Guest::read(Book &_book)
{
	return _book.read(name);
}

Member.h:

#pragma once
#include "Guest.h"
#include "Book.h"

class Member :
	public Guest
{
public:
	Member(char* _name, int _id);
	~Member(void);
private:
	int id;
public:
	int read(Book &_book);
	int checkOut(void);
	int checkIn(void);
};

Member.cpp:

#include "Member.h"

Member::Member(char* _name, int _id) : Guest(_name)
{
	id = _id;
}

Member::~Member(void)
{
}

int Member::read(Book &_book)
{
	Guest::read(_book);
}

int Member::checkOut(void)
{
	return 0;
}

int Member::checkIn(void)
{
	return 0;
}

Guys, I really need to solve this ASAP. I would really appriciate all of your help :)

Thanks

> friend int Member::checkOut();
> friend int Member::checkIn();
Replace these two lines with this:

friend class Member;

Edward doesn't have a solid reference on hand, but I don't think you can make a single non-static method be a friend. The friend has to be a non-member function or a whole class.

Thanks Edward, it works! :)

> friend int Member::checkOut();
> friend int Member::checkIn();
Replace these two lines with this:

friend class Member;

Edward doesn't have a solid reference on hand, but I don't think you can make a single non-static method be a friend. The friend has to be a non-member function or a whole class.

Edward doesn't have a solid reference on hand, but I don't think you can make a single non-static method be a friend. The friend has to be a non-member function or a whole class.

Actually a member function can also be friend (just like the two functions in the above Book class), quoting MSDN ...

A friend function is a function that is not a member of a class but has access to the class's private and protected members. Friend functions are not considered class members; they are normal external functions that are given special access privileges. Friends are not in the class's scope, and they are not called using the member-selection operators (. and ->) unless they are members of another class.

http://msdn.microsoft.com/en-us/library/h2x4fzdz(VS.80).aspx

I am with you. I had also read that!

But then why my above code is not doing any good?

Thanks

Actually a member function can also be friend (just like the two functions in the above Book class), quoting MSDN ...

A friend function is a function that is not a member of a class but has access to the class's private and protected members. Friend functions are not considered class members; they are normal external functions that are given special access privileges. Friends are not in the class's scope, and they are not called using the member-selection operators (. and ->) unless they are members of another class.

http://msdn.microsoft.com/en-us/library/h2x4fzdz(VS.80).aspx

mitrmkar is right, you just have to be careful about the circular dependency to get a clean compile:

#include <iomanip>
#include <iostream>
#include <sstream>

// Forward declare Test so Ed can make friends
class Test;

class Ed {
public:
  static void RunStatic(const Test& t);
  void RunInstance(const Test& t);
};

// Fully define Test so Ed's methods can use it
class Test {
  int x;
public:
  Test(): x(12345) {}
  friend void Ed::RunInstance(const Test&);
  friend void Ed::RunStatic(const Test&);
};

// Define Ed's methods to use Test
void Ed::RunStatic(const Test& t) 
{
  std::cout << t.x << '\n';
}

void Ed::RunInstance(const Test& t) 
{
  std::cout << t.x << '\n';
}

int main()
{
  Test t;
  Ed e;

  e.RunInstance(t);
  Ed::RunStatic(t);
}

You are needlessly including header files (.h) inside other header files. Try to do that as little as ever possible (in general). Instead of pulling in a whole header file inside another, learn to use forward declarations. For example, in guest.h you can use a forward declaration instead of pulling in book.h, i.e.

// guest.h
class Book; // <- satisfies the compiler wrt. int read([B]Book[/B] &_book);
// ...

and in guest.cpp you then would have the include

#include "Book.h"

The fixed headers are below, you need to add #include "book.h" in the guest.cpp

// guest.h
#pragma once

class Book;

class Guest
{
public:
	Guest(char* _name);
	~Guest(void);
protected:
	char* name;
public:
	int read(Book &_book);
};
// member.h
#pragma once

#include "Guest.h" // this one pulls in the forward declaration of Book too

class Member :
	public Guest
{
public:
	Member(char* _name, int _id);
	~Member(void);
private:
	int id;
public:
	int read(Book &_book);
	int checkOut(void);
	int checkIn(void);
};
// book.h
#pragma once

#include "Member.h"

class Book
{
[B]	< snip >[/B]
private:
	int checkOut(int _checkOutMember, char* _checkOutDate);
	int checkIn(char* _checkInDate);

	friend int Member::checkOut(void);
	friend int Member::checkIn(void);
};

Perfect! :)

Thank you all so much!

You are needlessly including header files (.h) inside other header files. Try to do that as little as ever possible (in general). Instead of pulling in a whole header file inside another, learn to use forward declarations. For example, in guest.h you can use a forward declaration instead of pulling in book.h, i.e.

// guest.h
class Book; // <- satisfies the compiler wrt. int read([B]Book[/B] &_book);
// ...

and in guest.cpp you then would have the include

#include "Book.h"

The fixed headers are below, you need to add #include "book.h" in the guest.cpp

// guest.h
#pragma once

class Book;

class Guest
{
public:
	Guest(char* _name);
	~Guest(void);
protected:
	char* name;
public:
	int read(Book &_book);
};
// member.h
#pragma once

#include "Guest.h" // this one pulls in the forward declaration of Book too

class Member :
	public Guest
{
public:
	Member(char* _name, int _id);
	~Member(void);
private:
	int id;
public:
	int read(Book &_book);
	int checkOut(void);
	int checkIn(void);
};
// book.h
#pragma once

#include "Member.h"

class Book
{
[B]	< snip >[/B]
private:
	int checkOut(int _checkOutMember, char* _checkOutDate);
	int checkIn(char* _checkInDate);

	friend int Member::checkOut(void);
	friend int Member::checkIn(void);
};

But after modifying my checkOut and checkIn methods in Member class, I get the following errors:

Error	1	error C2027: use of undefined type 'Book'	c:\project\library\library\member.cpp	23	
Error	2	error C2228: left of '.checkOut' must have class/struct/union	c:\project\library\library\member.cpp	23	
Error	3	error C2027: use of undefined type 'Book'	c:\project\library\library\member.cpp	31	
Error	4	error C2228: left of '.checkIn' must have class/struct/union	c:\project\library\library\member.cpp	31

Isn't class Book already known to Guest.h which is indirectly known to Member.cpp??

Here is modified Member.h and Member.cpp files:

// Member.h

#pragma once
#include "Guest.h"

class Member :
	public Guest
{
public:
	Member(char* _name, int _id);
	~Member(void);
private:
	int id;
public:
	int read(Book &_book);
	int checkOut(Book &_book);
	int checkIn(Book &_book);
};

// Member.cpp

#include <ctime>
#include "Member.h"

Member::Member(char* _name, int _id) : Guest(_name)
{
	id = _id;
}

Member::~Member(void)
{
}

int Member::read(Book &_book)
{
	return Guest::read(_book);
}

int Member::checkOut(Book &_book)
{
	char date [10];
	_strdate_s(date);
	
	return _book.checkOut(id, date);
}

int Member::checkIn(Book &_book)
{
	char date [10];
	_strdate_s(date);

	return _book.checkIn(date);
}

Thanks :)

But after modifying my checkOut and checkIn methods in Member class, I get the following errors:

Error	1	error C2027: [B]use of undefined type 'Book'[/B]

Isn't class Book already known to Guest.h which is indirectly known to Member.cpp??

With the setup you have, Book is declared only, so the compiler is unable to utilize the Book class's code i.e. you have to add #include "book.h" in the member.cpp.

Well, if I include Book.h in Member.cpp, this is what I get:

Book::checkOut and Book::checkIn are friends of Member!!

Error	1	error C2245: non-existent member function 'Member::checkOut' specified as friend (member function signature does not match any overload)	c:\project\library\library\book.h	50	
Error	2	error C2245: non-existent member function 'Member::checkIn' specified as friend (member function signature does not match any overload)	c:\project\library\library\book.h	51	
Error	3	error C2248: 'Book::checkOut' : cannot access private member declared in class 'Book'	c:\project\library\library\member.cpp	24	
Error	4	error C2248: 'Book::checkIn' : cannot access private member declared in class 'Book'	c:\project\library\library\member.cpp	32

With the setup you have, Book is declared only, so the compiler is unable to utilize the Book class's code i.e. you have to add #include "book.h" in the member.cpp.

Be careful now when you go over the files and change e.g. member function signatures, I suppose that you still have the original friends there, i.e:

class Book
{
...
friend int Member::checkOut(void);
friend int Member::checkIn(void);
};

If you do, you have to change these to match the new signatures, i.e.

friend int Member::checkOut(Book &_book);
friend int Member::checkIn(Book &_book);

Exprience counts sir!!
Thanks soo much! :)

Be careful now when you go over the files and change e.g. member function signatures, I suppose that you still have the original friends there, i.e:

class Book
{
...
friend int Member::checkOut(void);
friend int Member::checkIn(void);
};

If you do, you have to change these to match the new signatures, i.e.

friend int Member::checkOut(Book &_book);
friend int Member::checkIn(Book &_book);

OK, is there any better/faster way I can test the class library I just created for "Library" in Visual Studio 2005 than manually creating Main.cpp?

Thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.