I am new to C .In order to learn this, I am making a phonebook application which uses C concepts and functionalities. I have made two classes, phonebook
and features
; the phonebook
class uses all functions of features
, and the features
class uses functions of phonebook
.
But, when I am trying to pass a features
class object to phonebook
functions as an argument, the compiler gives an error that "features is not a type".
Why this error is coming – features
is a class here not a datatype? How can I resolve this issue?
Please see below code:
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<fstream>
#include<windows.h>
#include<iomanip>
#include<regex>
#define ADD_CONTACT 1
#define DELETE_CONTACT 2
#define EDIT_CONTACT 3
#define SHOW_CONTACT 4
#define DISPLAY_CONTACTS 5
#define SETTINGS 6
#define EXIT_MAIN 7
using namespace std;
class features;
//phone book page
class phonebook
{
//details of contact:
//mandatory details to store a contact
string first_name;
string last_name;
bool name_order;
string mobile_num;
string work_num;
string home_num;
//additional details for a contact
string company_name;
string job_title;
string email;
string location;
string dob;
bool favorite_flag;
bool friend_flag;
bool family_flag;
bool office_flag;
bool work_num_flag;
bool home_num_flag;
bool mobile_num_flag;
//flags of details whether present or not:
bool company_name_present=0;
bool job_title_present=0;
bool email_present=0;
bool address_present;
bool dob_present=0;
bool relation_present;
bool location_present=0;
//number of contact numbers present for each contact
//kind of number either work or home or mobile or telephone_home or telephone_office
int num_kind;
//link for linked list
phonebook* link;
//bool allocate_mem_to(phonebook* &);
bool check_number_valid(string &);
bool check_email_valid(string &);
void reverse_linked_list(phonebook* &);
void add_in_sorted_order(phonebook* &,phonebook* &,bool,bool);
void print_all_the_details(phonebook* &);
friend void operator>>(istream&,phonebook*&);
friend void operator<<(ostream&,phonebook*&);
public:
phonebook(){
favorite_flag=0;
friend_flag=0;
family_flag=0;
office_flag=0;
mobile_num_flag=0;
work_num_flag=0;
home_num_flag=0;
company_name_present=0;
job_title_present=0;
email_present=0;
location_present=0;
dob_present=0;
relation_present=0;
name_order=0;
link=NULL;
}
~phonebook(){}
friend class features;
void add_contact(phonebook* &,features obj);
void delete_contact(phonebook* &,features obj);
void edit_contact(phonebook* &,features obj);
void show_contact(phonebook* &,features obj);
void display_contacts(phonebook* &,features obj);
void features();
bool phonebook_login_operations();
};
class features
{
bool sort_flag;
bool name_order_flag;
bool friends_display;
bool family_display;
bool office_display;
bool all_contacts_display;
bool only_favourites;
public:
friend class phonebook;
features();
~features()
{
}
void add_to_favourites(phonebook* &);
void contacts_to_display();
void sort_by();
void name_order();
void print_main_admin_menu();
};
void phonebook::add_contact(phonebook* &head,features obj)//Here complier gives error"features is not type"
{
phonebook *temp_obj=NULL,*read_obj=NULL,*traverse_pointer=NULL;
temp_obj=new phonebook;
cin>>temp_obj;
bool sort_flag_1=0;
bool name_order_flag_1=0;
ifstream file_in;
file_in.open("phonebook_contacts.txt");
if(file_in)
{
if(head==NULL)
{
if(obj->sort_flag == false)
sort_flag_1=0;
else
sort_flag_1=1;
if(obj->name_order_flag == false)
name_order_flag_1=0;
else
name_order_flag_1=1;
while(file_in)
{
read_obj=new phonebook;
file_in.read((char*)read_obj,sizeof(*read_obj));
add_in_sorted_order(head,read_obj,sort_flag_1,name_order_flag_1);
}
}
add_in_sorted_order(head,temp_obj,sort_flag_1,name_order_flag_1);
file_in.close();
ofstream file_in_out;
file_in_out.open("phonebook_contacts.txt");
for(traverse_pointer=head;traverse_pointer;traverse_pointer=traverse_pointer->link)
file_in_out.write((char*)traverse_pointer,sizeof(*traverse_pointer));
file_in_out.close();
}
else
{
ofstream file_out;
file_out.open("phonebook_contacts.txt");
file_out.write((char*)temp_obj,sizeof(temp_obj));
file_out.close();
}
}
CodePudding user response:
features
is a class here not a datatype.
Are you sure about that? You may know what you mean, but the compiler is confused … because of this line near the end of the definition of the phonebook
class:
void features();
So, to the compiler, the name, features
could refer to either the class of that name or to the member function of the same name. Adding the class
tag will inform the compiler that you do, indeed, mean the class (and not the member function – which is 'in scope' here, because add_contact
is a member of phonebook
)1.
Alternatively, as you don't appear (in the code you've shown) to ever actually use the void features()
function, just comment that out (or remove it).
Also, with either of those corrections applied, you will then have errors where you use code like obj->sort_flag
and obj->name_order_flag
inside add_contact
. The obj
parameter is not declared as a pointer: so, either make it one (i.e. void phonebook::add_contact(phonebook*& head, features* obj)
, in both the definition and the in-class declaration, or change the two ->
operators to .
. (The former is probably the best option, though that will ultimately depend on your use-case.)
1 Actually, the compiler isn't really "confused" at all: it is obliged to interpret features
as referring to the member function, because the argument is inside the phonebook
class scope. As an alternative to using the class
tag before features
, you could also add the global scope-resolution operator, ::
, like this:
void phonebook::add_contact(phonebook*& head, class features obj)
or:
void phonebook::add_contact(phonebook*& head, ::features obj)