I get the following error compiling the code below:
Student.cpp:20:9: error: ‘std::string Student::name’ is private within this context
20 | name = _name;
| ^~~~
Student.cpp:7:12: note: declared private here
7 | string name;
#include <iostream>
using namespace std;
class Student
{
private:
string name;
};
class UndergraduateStudent : public Student
{
};
class GraduateStudent : public Student
{
};
class Freshman : public UndergraduateStudent
{
Freshman(string _name)
{
name = _name;
}
};
What could be the reason for this?
I want to keep UndergraduateStudent class as abstract
I had a hard time understanding public, private, and protected when I was learning object-oriented programming in C++, and thought that I would share a few thoughts to hopefully clear some of this up.
First of all, public, private, and protected are used to determine the level of accessibility of a variable or method in a class. If you declare a variable as private, you can access that variable inside of the class that it was declared in, but nowhere else. With protected, you may access that variable in the child classes of the class it was declared in. And with public, you can access that variable anywhere.
So what does this mean?
Using your code, we start off with this:
#include <iostream>
using namespace std;
class Student
{
private:
string name;
};
class UndergraduateStudent : public Student
{
};
class GraduateStudent : public Student
{
};
class Freshman : public UndergraduateStudent
{
Freshman(string _name)
{
name = _name;
}
};
The reason that you got a compile error is that you tried to access the variable "name" in the Freshman class. Freshman is a child class of Student (well, it's actually a child class of Undergraduate Student which is a child of student, but the concept still applies). Because of this, any method in the Freshman class will only be able to access protected and public variables and methods in the Student class. Therefore, if you want to access "name" in the Freshman class, you must change it from private to either protected or public.
However, after doing this, you might wonder how to access private and protected variables from outside of the class? In main() how would you get the value of a freshman's name if it is private or protected? The answer to this is getters and setters. Modifying your code a little bit, you get something like this:
#include <iostream>
using namespace std;
class Student
{
protected:
string name;
public:
string getName(){
return name;
}
void setName(string _name){
name = _name;
}
};
class UndergraduateStudent : public Student
{
};
class GraduateStudent : public Student
{
};
class Freshman : public UndergraduateStudent
{
public:
Freshman(){}
Freshman(string _name)
{
name = _name;
}
};
As you can see, I added a couple of public methods in Student, getName() and setName(). I also added some constructors in the Freshman class. The important part about these Student methods is that they are public, and can be accessed anywhere. It's not difficult code to understand, essentially getName() returns the value of the private variable "name", and setName() is able to change that value.
So lets say that in main() I wanted to create a Freshman object, and declare her name as Sarah, and print out that result.
int main(){
Freshman freshman("Sarah");
cout << freshman.name;
}
If I did this, I would get a compile error, because I am trying to access the protected variable "name". If I wanted to access the value, I would have to access it through the public method getName(). Therefore:
int main(){
Freshman freshman("Sarah");
cout << freshman.getName();
}
This would print out the correct result of "Sarah". Now, let's say that I spelled her name wrong, and it turns out there's no 'h' in her name. Then, I would have to call the public method of setName in order to change her name to something else.
int main(){
Freshman freshman("Sarah");
freshman.setName("Sara");
cout << freshman.getName();
}
This would now output the value of "Sara". These are just some basic examples of how to use private, protected, and public, sorry if it was a little bit lengthy. I hope that it can help you if you don't quite understand exactly how to use them yet. Just practice, it comes after doing it a few times.
Related
I am learning OOP in C++, and I have written this piece of code to learn more about inheritance.
#include<bits/stdc++.h>
using namespace std;
class Employee {
public:
string name;
int age;
int weight;
Employee(string N, int a, int w) {
name = N;
age = a;
weight = w;
}
};
// this means the class developer inherits from employee
class Developer:Employee {
public:
string favproglang; //this is only with respect to developer employee
// now we will have to declare the constructor
Developer(string name, int age, int weight, string fpl)
// this will make sure that there is no need to reassign the name, age and weight and it will be assigned by the parent class
:Employee(name, age, weight) {
favproglang = fpl;
}
void print_name() {
cout << name << " is the name" << endl;
}
};
int main() {
Developer d = Developer("Hirak", 45, 56, "C++");
cout << d.favproglang << endl;
d.print_name();
cout << d.name << endl; //this line gives error
return 0;
}
Here the developer class is inheriting from the employee class, but when I am trying to print the name of the developer from the main function cout << d.name << endl; I am getting this error 'std::string Employee::name' is inaccessible within this context.
I am not getting why I am getting this error? I have declared all the attributes as public in the parent class. This error is not their when I am trying to access the name from the developer class itself as you can see in the function print_help(). Moreover I can also print d.favproglang from the main function, but then why not d.name? Any help will be highly appreciated. Thank you.
This is because the default access control for inheritance is "private".
If you change this:
// this means the class developer inherits from employee
class Developer: Employee {
to this:
// this means the class developer inherits from employee
class Developer: public Employee {}
By default, class inheritance is "private" inheritance and struct inheritance is "public" inheritance. Private inheritance means public and protected members of the base class will be treated like private members by the child class.
You can override this default behaviour by explicitly writing public, private or protected in front of the base class name.
Search "c++ base class members access control" to learn more.
There are 2 solutions(straightforward) to this.
Solution 1
Replace the class keywords for both the Employee and Developer class with the keyword struct. Note even if you replace class keyword for Developer with struct and leave the class keyword as it is for Employee then also this will work.
Solution 2
Add the keyword public in the derivation list as shown in the next line:
class Developer:public Employee
This question already has answers here:
Allowing access to private members
(4 answers)
Can I access private members from outside the class without using friends?
(27 answers)
Closed 1 year ago.
I want to change the data in the private members but the delete_Data() function is outside the class so how to get the members without being declared in the class and erase them using the delete_Data() functionthe only way it works for me it to declare delete_data()function in the class on public section but
our teachers said you should only use this method
i need help pls thank you
for eg
Enter your Name: John
Enter your id: 1234
Name: John
ID:1234
Name :
ID:0
#include <iostream>
#include <string.h>
using namespace std;
class data{
private:
string name;
int id;
public:
void add_Data()
{
cout<<"Enter you Name :";
cin>>name;
cout<<"Enter your id :";
cin>>id;
}
void display_Data(){
cout<<"Name :"<<name<<endl;
cout<<"ID :"<<id<<endl;
}
};
void delete_Data(){
name="";
id=0;
}
int main(){
data one;
one.add_Data();
one.display_Data();
delete_Data()
one.display_Data;
return 0;
}
Usually✝, the member functions and the friends of the class can access the private members of a class, via an instance of the class.
Therefore, in your case, make the delete_Data function as friend function.
class data
{
private:
std::string name;
int id;
public:
// ...
friend void delete_Data(data& obj);
};
void delete_Data(data& obj)
{
obj.name = "";
obj.id = 0;
}
Now in the main()
data one;
delete_Data(one);
Also note that, you need to pass an instance of the data class to access the members of the class.
Side notes:
✝There are other tricky ways, by which we can also
access the member. However, the whole point of the
public/protected/private modifiers, is not to do that.
See more:
Can I access private members from outside the class without using friends?
Also see
Why is "using namespace std;" considered bad practice?
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
class person {
private: char name[50];
int age;
public: void get_name() {
cout<<"Enter name"<<endl;
gets(name);
}
void put_name() {
cout<<"Name : ";
puts(name);
cout<<endl;
}
void get_age() {
cout<<"Enter age"<<endl;
cin>>age;
}
void put_age() {
cout<<"Age : "<<age<<endl;
}
};
class student : public person {
private : int roll;
public : void get_roll() {
cout<<"Enter roll"<<endl;
cin>>roll;
}
void put_roll() {
cout<<"Roll : "<<roll<<endl;
}
};
int main() {
student A;
A.get_name();
A.get_roll();
A.get_age();
A.put_name();
A.put_age();
A.put_roll();
getch();
clrscr();
return 0;
}
There are following queries:
If private members of class person are not inherited in class student then how can an instance of class student store values in them?
Shouldn't the variables just not exist in the class student?
Note: I am using old compiler for a college project.
If a Student wants to access the Person fields, the simplest way is make them protected, so they can be accessed by all derived class of Person.
Another way is use public getter/setter methods (you can even set them protected, but at this point is better use protected fields), in this way all classes can see and set the fields of Person.
Indeed, even if a variable is declared private in the base class, it exist in the derived class ( a Student is in any case a Person, so the field in Person must be initialized) but it can't be reached by her.
A is an object of type Student and it can access protected or public member function and data member of class Person. Now answer to your query, you are trying to use the function of class Person using object of class Student which is possible (as inherited publicly) and since the function and those private data member are part of same class (Person), so those function can use the variable.
Note : private, public and protected member have no effect within same class.
I am new into classes, and I have been trying to create this simple class code but every time I get an error. It works fine when I don't use the access specifier private, but I want to practice how to use private. Could you please tell me what's wrong?
#include <iostream>
#include <string>
using namespace std;
class Student
{
private:
string name;
int ID;
public:
void setName(string);
string getName();
void setID(int);
int getID();
};
void Student::setName(string n)
{
name=n;
}
string Student::getName()
{
cout<<name;
return name;
}
void Student::setID(int i)
{
ID=i;
}
int Student::getID()
{
cout<<ID;
return ID;
}
int main ()
{
Student S;
cout<<"Enter Student name: ";
cin>>S.name;
cout<<"Enter students ID: ";
cin>>S.ID;
cout<<"The student's name is "<< S.name<<endl;
cout<<"The student's ID is "<< S.ID<<endl;
return 0;
}
In your main function you are trying to access the name and IDmember of your class. Which are private... Since you are outside the scope of the class Student, the compiler shouts at you.
You should do this (as you've implemented setters and getters):
int ID(0);
std::string name;
std::cin >> name;
S.setName(name);
std::cin >> ID;
S.setID(ID);
You have to access your private fields using setters/getters to set or retrieve their values, you can't use them with the class dot notation because they're private and you can access to them only using public methods
What's wrong : You are accessing private members without using a class member function (outside of the class scope).
Private members are useful when you want to protect a value from uncontrolled access. Like when the modification of a value must undergo a certain verification (which would be implemented in class functions).
In your code, you made sure name and ID are private, which means both can only be accessed using class functions (like the constructor or the getter and setter).
If you wanted, you could create a class named classroom (which would contain many students, stored in a vector).
In that class, you could make sure than when a student is added, it's ID is automatically generated and does not equal any other ID. In that case, it would be important to put the student vector private since it would require some sort of validation.
class Student
{
private: // anything that wants to access members below
// this must be defined as a class member, or the equivalent
string name;
int ID;
public:
void setName(string); // can access private members
string getName(); // can access private members.... should be const
void setID(int); // can access private members
int getID(); // can access private members, should be const
};
i have two c++ classes, one which inherits an abstract base class for a student database.
The base class is the record which contains all the student information (name, id vector of courses & marks):
class student{
protected:
string fName,sName;
int id;
vector<string> cname;
vector<double> cmark;
public:
virtual ~student();
virtual void addClass(string name, double mark)=0;
};
I Need to be able to access the vector cname and cmark in the addCourse function in the below class
class degree : public student{
public:
degree(string f, string s, int i){
this->setName(f,s);
this->setID(i);
}
~degree();
void AddCourse(string name, int mark){
}
I dont know how to do this without making a set function in the base class like i have done with the degree constructor.
I could just make a set function in the base class but i would rather some method of initializing the inherited elements without using functions, just to make the code less messy, is this possible? i thought about using this->cname but that gave me errors.
I Need to be able to access the vector cname and cmark in the addCourse function in the below class
Just access them, they are protected, so derived classes have access:
void AddCourse(string name, int mark){
cname.push_back(name);
cmark.push_back(mark);
}