How to start with Classes in c++ - c++

I at classes and objects of C++, where i am facing difficulties to understand the concept of deceleration of a class, for which i have make a little program which is not compiling, anybody will guide me?
#include <iostream>
using namespace std;
class myClass{
friend increment(myClass, int);
private:
int topSecret;
public:
myClass(){
topSecret = 100;
}
void display(){
cout<<"The value of top Secter is"<<topSecret;
}
};
void increment(myClass A, int i){
A.topSecret += i;
}
int main() {
myClass x;
x.display();
increment(x,10);
x.display();
}

Change
friend increment(myClass, int);
to
friend void increment(myClass &, int);
That should fix your compilation errors.
To modify the original object passed to a function, declare the function to take a reference:
void increment(myClass A, int i){
to
void increment(myClass &A, int i){

Arun's answer shows you how to fix your compilation error, but this is not how you should design a class. Defining non-member friend functions to access your internal data will often lead to maintenance issues and bugs. You would be better off either declaring increment as a public member function, or defining getter and setters for your class:
class myClass{
private:
int topSecret;
public:
//use initialization list instead of setting in constructor body
myClass() : topSecret(100) {}
//getter, note the const
int GetTopSecret() const { return topSecret; }
//setter, non-const
void SetTopSecret(int x) { topSecret = x; }
//member version
void increment (int i) { topSecret += i; }
};
//non-member version with setter
//note the reference param, you were missing this
void increment(myClass &A, int i){
A.SetTopSecret(A.GetTopSecret() + i);
}

Add void bebore increment in class definition as Arun A.S said.
You can't change A.topSecret in increment function because you take object by value, so you just change temporary object, use instead void increment(myClass &A, int i)

Related

How to apply constant reference parameter on this code?

This code is passing object to a function and I want to apply constant reference parameter on this code.
class Test
{
int num;
public :
void setNum(int z)
{
num=z;
}//end mutator
int getNum()
{
return num;
}//end accessor
};//end class
void storeNumber(Test &n)
{
int a=10;
n.setNum(a);
}
void displayNumber(Test n)
{
cout<<"number="<<n.getNum()<<endl;
}
int main()
{
Test t;
t.setNum(5);
cout<<t.getNum()<<endl;
storeNumber(t);//pass by reference;
displayNumber(t); //pass by value
cout<<t.getNum();
}
This code is passing object to a function and I want to apply constant reference parameter on this code.
Any help!!
You can do for example void displayNumber(const Test &n) but then if you call methods of the Test class, they must have the const qualifier too (for example int getNum() const). If you pass Test as const & to a function, then you won't be able to use void setNum(int z) function as it violates the constantness of the class.
Edit:
Here is the full code:
class Test
{
int num;
public :
void setNum(int z)
{
num=z;
}//end mutator
int getNum() const
{
return num;
}//end accessor
};//end class
void storeNumber(Test &n)
{
int a=10;
n.setNum(a);
}
void displayNumber(const Test &n)
{
cout<<"number="<<n.getNum()<<endl;
}
int main()
{
Test t;
t.setNum(5);
cout<<t.getNum()<<endl;
storeNumber(t);//pass by reference;
displayNumber(t); //pass by value
cout<<t.getNum();
}

Why can't this derived object access the base class' post-decrement method?

class Player
{
private:
int score;
public:
Player(int number);
~Player();
int get_score() { return score; }
Player& operator--();
};
Player::Player(int number)
{
score = number;
}
Player::~Player()
{
}
//-----
//Please turn your attention to this function
//-----
Player& Player::operator--() {
score--;
return *this;
}
Hello all, in the above class, I have overloaded the post-decrement operator to decrease the 'score'. There are two sub classes derived from this class - Computer and Human. From my understanding, they should also have access to this function. However, when I try:
Computer comp_; Human player_;
comp--;
human--;
I get an error saying: 'neither of these classes define this operator or a conversion to a type accessible to the predefined operator'. I am not allowed to redefine this function within the sub classes.
It would really help if someone could help me figure out how to get this code working! <3
You're trying to use the post-decrement operator, but you've declared the pre-decrement operator!
To make this code work, either use pre-decrement comp--; => --comp;. Or switch to defining the post-decrement operator Player& operator--(); => Player& operator--(int);. See a working example here: ideone.
For more on what each decrement/increment operator looks like, see the cppreference page.
The post decrement operator should look like this:
T T::operator--(int); // Inside class definition
T operator++(T& a, int); // Outside class definition
and it's supposed to return a copy of the object like it looked before you decreased its value.
class Player
{
private:
int score;
public:
Player(int number);
virtual ~Player();
int get_score() { return score; }
template<typename T>
friend T& operator--(T& p) { // pre
--p.score;
return p;
}
};
Player::Player(int number) : score(number) {}
Player::~Player() {}
template<typename T>
T operator--(T& p, int) { // post
T save(p);
--p; // using pre
return save;
}
The problem comes from the fact that you only define pre-increment operator.
see https://en.cppreference.com/w/cpp/language/operator_incdec
The pre-increment returns a reference, however the post increment returns a value therefore if you need to retain the type of the object returned. I would define the post-increment as a template and use the implementation of the pre-increment.
namespace Game
{
class Player
{
private:
int score;
public:
Player(int number);
~Player();
int get_score() { return score; }
Player& operator--();
};
Player::Player(int number)
{
score = number;
}
Player::~Player()
{
}
Player& Player::operator--() {
score--;
return *this;
}
template <class T> T operator--(const T& a, int)
{
T save(a);
save--;
return save;
}
class Human : public Player
{
public:
Human(int player) :Player(player) {}
};
class Computer : public Player
{
public:
Computer(int player) :Player(player) {}
};
}
example
int main()
{
Game::Human h(2);
Game::Human h2 = h--;
}

Return function type example in C++

Current get() member function in class MyClass is defined as below, the return type is const int&. My question is what would be the difference if I defined get() function as
int& get() const
or
int get() const
? And which way is recommended?
#include <iostream>
using namespace std;
class MyClass {
int x;
public:
MyClass(int val) : x(val) {}
const int& get() const {return x;}
};
void print (const MyClass& arg) {
cout << arg.get() << '\n';
}
int main() {
MyClass foo (10);
print(foo);
return 0;
}
There's really nothing wrong with this code; logically it accomplishes more or less the same thing after the compiler inlines the get() method.
There's quite a big difference in some degenerate callers though:
const int *iptr = &foo.get(); // returns the address of x in the class.
On the other hand had you declared as follows:
class MyClass {
int x;
public:
MyClass(int val) : x(val) {}
const int get() const {return x;}
};
const int *iptr = &foo.get(); // Error!
I don't see any good reason for int& here. If you don't have one, people will frown on this code. Normally if people are expected to keep pointers to things around you don't return them by reference. The only reason you would want to return a pointer to a member is so that somebody can auto-pickup changes to it; and I have never seen a good use for that though I can imagine why some such thing might exist.
As for selbie's comment about assigning to it; it's a const reference; assigning to it is a compile time error.

Are there any alternatives to making const version of class?

In C++ I'm often facing a situation when I need to prepare const and non-const version of class in analogy to const_iterator and iterator from standard library.
class const_MyClass
{
public:
const_MyClass(const int * arr):
m_arr(arr)
{
}
int method() const; //does something with m_arr without modifying it
private:
const int * m_arr;
}
class MyClass
{
public:
MyClass(int * arr):
m_arr(arr)
{
}
int method() const; //does something with m_arr without modifying it
void modify(int i); //modify m_arr
private:
int * m_arr;
}
The problem with this is that I need to repeat whole code of const_MyClass in MyClass and distribute any changes in API to both classes. Thus sometimes I inherit const_MyClass and do some const_casts, which also isn't perfect and pretty solution. Still when I want to pass const_MyClass instance by reference it looks moronic:
void func(const const_MyClass & param)
Instance param is marked with two "consts", and it has only const methods...
This is where const constructors would be handy, but are there any existing alternatives?
Some use examples to explain problem better:
//ok to modify data
void f(int * data)
{
MyClass my(data);
my.modify();
...
}
//cant modify data, cant use MyClass
void fc(const int * data)
{
const_MyClass my(data);
int i = my.method();
...
}
You can make a template class to act as a base, like this:
template<typename T>
class basic_MyClass
{
public:
basic_MyClass(T * arr) :m_arr(arr) {}
int method() const; //does something with m_arr without modifying it
private:
T * m_arr;
};
Then, for your const version, since it doesn't add anything, you can just use a typedef:
typedef basic_MyClass<const int> const_MyClass;
For your non-const version, you can inherit:
class MyClass : public basic_MyClass<int>
{
public:
using basic_MyClass::basic_MyClass; // inherit all the constructors
void modify(int i); //modify m_arr
};
Have you considered simply tracking two pointers and raising exceptions from the mutable operations when no mutable value is available? Maybe an example will help describe what I am thinking of.
class MyClass
{
public:
MyClass(int *mutable_data):
m_mutable_view(mutable_data), m_readonly_view(mutable_data)
{
}
MyClass(const int *immutable_data):
m_mutable_view(NULL), m_readonly_view(immutable_data)
{
}
int retrieve_value(int index) {
return m_readonly_view[index];
}
void set_value(int index, int value) {
require_mutable();
m_mutable_view[index] = value;
}
protected:
void require_mutable() {
throw std::runtime_error("immutable view not available");
}
private:
const int *m_readonly_view;
int *m_mutable_view;
};
The idea is pretty simple here - use a sentinel value to indicate whether modifications are possible or not instead of depending on the type system to do that for you. Personally, I would think about doing the inheritance based approach that #BenjaminLindley suggested but I wanted to present a slightly different solution that might not have occurred to you.
After talk with Neil Kirk I realized what I was doing wrong. I started by separating data from logic as he suggested.
This attempt resulted in two classes MyClassPtr and const_MyClassPtr. They only provide functions for data access (like iterators) and may look like that:
class const_MyClassPtr
{
public:
const_MyClassPtr(const int * arr);
int operator [](int i) const;
const int * ptr() const;
private:
const int * m_arr;
}
class MyClassPtr
{
public:
MyClassPtr(int * arr);
int operator [](int i) const;
int & operator [](int i);
const int * ptr() const;
int * ptr();
//promotion to const pointer
const_MyClassPtr () const {return const_MyClassPtr(m_arr);}
private:
int * m_arr;
}
Now it is clear that objects of these classes should be treated like pointers, so when I use them as function parameters I pass them by value!
void func(const_MyClassPtr param) //instead of void func(const const_MyClass & param)
To provide methods I have created MyClassOp class template and used static polymorphism.
template <class DERIVED>
class MyClassOp
{
public:
const DERIVED & derived() const {return static_cast<const DERIVED &>(*this)}
DERIVED & derived() {return static_cast<DERIVED &>(*this)}
int method() const; //operates on derived() const
void modify(int i); //operates on derived()
}
MyClassOp is a collection of methods. It does not have state. In general it is a trait. To make these methods accessible I overloaded -> and * operators
class const_MyClassPtr : private MyClassOp<const_MyClassPtr>
{
public:
const MyClassOp<MyClassPtr> * operator ->() const {return this;}
const MyClassOp<MyClassPtr> & operator *() const {return *this;}
...
}
class MyClassPtr : private MyClassOp<MyClassPtr>
{
public:
MyClassOp<MyClassPtr> * operator ->() {return this;}
MyClassOp<MyClassPtr> & operator *() {return *this;}
...
}
This works O.K., but is a bit cumbersome. If I have for example equality operator I need to write something like *myptr1 == myptr2 to compare values kept by two MyClassPtr objects (it's easy to make a mistake and compare myptr1 == myptr2 or expect that something like *myptr1 == *myptr2 could work). Also when I have allocating type:
class MyClass : public MyClassOp<MyClass>
{
MyClass(int x, int y, int z);
...
int m_arr[3];
}
I would want to be able to use temporaries as function arguments.
void f(const_MyClassPtr my);
//use temporary when calling f()
f(MyClass(1, 2, 3));
I can do this by providing conversion operators or conversion constructors (that convert MyClass to const_MyClassPtr). But then const_MyClassPtr behaves more like reference than pointer. If iterators are generalization of pointers then why one could not imitate reference? Therefore I divided MyClassOp into two parts (const and non const) and replaced -> and * operators implemented by const_MyClassPtr and MyClassPtr with public inheritance and changed their names to ressemble reference. I ended up with following structures.
MyClassOp : public const_MyClassOp
const_MyClassRef : public const_MyClassOp<const_MyClassRef>
MyClassRef : public MyClassOp<MyClassRef>
MyClass : public MyClassOp<MyClass>
However const_MyClassRef and MyClassRef are not perfect generalization of reference as it impossible to imitate some of C++ reference properties, so Ref suffix is there to denote reference-like structure.
Maybe you can find some hints in effective c++ item 4 "Avoid duplication in const and non-const Member function"
I may summarize like following ( it makes you avoid code duplication even if using somewhat ugly cast ):
struct my_class
{
my_class(int x):_x(x){};
const int& method(void) const;
int& method(void);
int _x;
};
const int& my_class::method(void) const //func for const instance
{
return _x;
}
int& my_class::method(void) //func for normal instance
{
return const_cast<int& >(static_cast<const my_class& >(*this).method()) ;
}
int main()
{
my_class a(1);
const my_class b(2);
a.method() = 5;
cout << a.method() << endl;
//b.method() = 4; //b is const, wont compile
cout << b.method() << endl;
return 0;
}

Comparator that requires access to private members of class

Basic structure of my code is
class Foo{
vector<string> _lines;
vector<int> _n;
public:
...
bool Comp(int i, int j){
return something that depends on _lines;
}
...
void doSomething(){
std::sort(_n.begin(), _n.end(), Comp);
}
...
};
But I get
error: no matching function for call to
‘sort(std::vector<unsigned int>::iterator,
std::vector<unsigned int>::iterator, <unresolved overloaded function type>)
How can I resolve this problem WITHOUT COPYING THE VECTORS? (because these vectors are very very big 17179508 strings to be precise).
std::sort expects a binary predicate taking two ints in this case. A member function takes an implicit first parameter, so in all Foo::Comp takes three parameters. You could pass a non-member function, or a static member function, but neither of these would have access to Foo's data members. The simples way is to use std::bind to bind this to the first parameter of the member function:
#include <functional> // for std::bind
#include <vector>
#include <algorithm>
class Foo{
vector<string> _lines;
vector<int> _n;
public:
...
bool Comp(int i, int j){
return something that depends on _lines;
}
...
void sort(){
using namespace std::placeholders;
std::sort(_n.begin(), _n.end(), std::bind(Comp, this, _1, _2));
}
...
};
The most obvious initial suggestion is to aggregate your int and string into a struct or std::pair, have a single vector with the aggregate in it, and then sort that vector of aggregates.
But if the two vectors are in fact independent, I would suggest using an external predicate, instead of your Comp method:
struct Comp
{
explicit Comp(vector<string>& lines) : lines_(lines) { }
bool operator()(int i, int j) const
{
return something that depends on lines_;
}
vector<string>& lines_;
};
Then call it:
void doSomething()
{
std::sort(_n.begin(), _n.end(), Comp(_lines));
}
What about using your object as the comparator itself. This compiles on gcc 4.6:
class Foo{
std::vector<std::string> _lines;
std::vector<int> _n;
public:
bool operator()(int i, int j){
return false;
}
void doSomething(){
std::sort(_n.begin(), _n.end(), *this);
}
};
Edit:
Turns out that was not such a good idea, copying an object with 17M strings would incur a huge penalty. A nested class, taking a pointer, could be used instead. That would also allow us to have different comparators:
class Foo
{
std::vector<std::string> _lines;
std::vector<int> _n;
class Bar
{
public:
Bar( const Foo * foo ) : _foo( foo ) {}
bool operator()( int i, int j )
{
act on _foo->_lines
}
private:
const Foo * _foo;
};
public:
void doSomething(){
std::sort(_n.begin(), _n.end(), Bar(this));
}
};