Hi, I've created a class which has three constructors, two integer members & one const int member. So for one constructor I'm using initializer list to assign const int member but I am getting error in other two constructors
Here is my code:
class base
{
public:
base();
base(const int _count);
base(int a ,int b);
~base();
protected:
int m_ia , m_ib;
const int count;
};
base::base()
{
}
base::base(const int _count):count(_count)
{
}
base::base(int a , int b)
{
m_ia = a ;
m_ib = b;
}
base::~base()
{
}
void main()
{
base *obj2 = new base(1000);
getchar();
}
Number of Errors:2
1.'base::count' : must be initialized in constructor base/member initializer list at base()
2.'base::count' : must be initialized in constructor base/member initializer list at base(int a ,int b)
You should probably make sure all your constructors are initializing all member variables, not just the one's being passed in as arguments. I'd rewrite your constructors as
base::base()
: m_ia() // value initializes i.e. sets to 0
, m_ib()
, count()
{
}
base::base(const int _count)
: m_ia()
, m_ib()
,count(_count)
{
}
base::base(int a , int b)
: m_ia(a)
, m_ib(b)
, count()
{
}
And if you have a C++11 compiler that supports delegating constructors, you could create a 4 constructor that takes 3 arguments and have the other constructors delegate to that one.
base::base()
: base(0, 0, 0)
{
}
base::base(const int _count)
: base(0, 0, _count)
{
}
base::base(int a , int b)
: base(a, b, 0)
{
}
base::base(int a , int b, int count)
: m_ia(a)
, m_ib(b)
, count(count)
{
}
The last constructor can be made private if you don't want it to be part of the class interface.
In c++11 you can have
protected:
int m_ia , m_ib;
const int count = 0;
It works in VS 2013.
As per standard C++ and you current code you have to Initialize your const variable in constructor using initialize list so code can be modified as below :
#include"iostream"
using namespace std;
class base
{
public:
base();
base(const int _count);
base(int a ,int b, const int _count);
~base();
protected:
int m_ia , m_ib;
const int count;
};
base::base():count(0)
{
}
base::base(const int _count):count(_count)
{
}
base::base(int a , int b, const int _count):count(0)
{
m_ia = a;
m_ib = b;
}
base::~base()
{
}
int main()
{
base *obj2 = new base(1000);
getchar();
return 0;
}
Related
Program works but I am not sure what is wrong with constructor since every time program runs it gets this error "warning: base class 'Alat' is uninitialized when used here to access 'Alat::ime' [-Wuninitialized]". I suppose it's something wrong how I called a constructor from base class but I am not sure what is problem. Really need help, tnx in advance.
#include <iostream>
#include <string>
using namespace std;
class Alat{
protected:
string ime;
int serBr;
int cena;
public:
void setIme(string i);
string getIme();
void setSerBr(int sb);
int getSerBr();
void setCena(int c);
int getCena();
Alat();
Alat(string i, int sb, int c)
:ime(i),
serBr(sb),
cena(c)
{}
void info();
~Alat();
};
#include "Alat.h"
class Rucni : public Alat{
protected:
int minGodKor;
public:
Rucni():Alat(ime, serBr, cena) //I think here is problem, is it wrong called?
{}
int getminGodKor();
void setminGodKor(int min);
void info();
~Rucni();
};
Let the child default constructor call the default parent constructor, and create another child constructor with parameters to call the corresponding one of the parent:
#include <string>
using std::string;
class Alat
{
protected:
string ime;
int serBr;
int cena;
public:
void setIme(string i)
{
ime = i;
}
string getIme()
{
return ime;
}
void setSerBr(int sb)
{
serBr = sb;
}
int getSerBr()
{
return serBr;
}
void setCena(int c)
{
cena = c;
}
int getCena()
{
return cena;
}
Alat()
{
}
Alat(string i, int sb, int c) : ime(i), serBr(sb), cena(c)
{
}
~Alat()
{
}
};
class Rucni : public Alat
{
protected:
int minGodKor;
public:
Rucni() // implicit call of the parent default constructor
{
}
Rucni(string i, int sb, int c) : Alat(i, sb, c) // explicit call of the corresponding parent constructor
{
}
int getminGodKor()
{
return minGodKor;
}
void setminGodKor(int min)
{
minGodKor = min;
}
~Rucni()
{
}
};
int main()
{
Rucni r;
return 0;
}
I keep getting three errors that all relate to "Call to implicitly deleted default constructor of ____. Would anyone happen to know why this is?
/Users/vivekreddy/Desktop/Vivek/School/Spring 2016/CS32/project 3/project 3/Player.cpp:114:18: Call to implicitly-deleted default constructor of 'BadPlayerImpl'
#include "provided.h"
#include <iostream>
#include <string>
using namespace std;
class HumanPlayerImpl:public Player
{
public:
virtual bool isInteractive() const { return true;};
int chooseMove(const Scaffold& s, int N, int color);
};
class BadPlayerImpl: public Player
{
public:
int chooseMove(const Scaffold& s, int N, int color);
};
class SmartPlayerImpl: public Player
{
public:
virtual bool isInteractive() const { return true;};
int chooseMove(const Scaffold& s, int N, int color);
};
//implementations
//put virtual in front of implementations only or declarations here as well?
int HumanPlayerImpl::chooseMove(const Scaffold& s, int N, int color) //goal is to get N in a row, return the column necessary to put the checker so we could do that. otherwise return -1. can make the column be arbitrary
{
//algorithm is inputting N so maybe don't need this check?
if (N>s.cols()||N<=0) {
cout<<"Enter a number within the valid range of columns you specified";
return -1;
}
if(s.numberEmpty()==0)
{
return -1;
}
int columnnum;
while (columnnum<=s.cols()||columnnum<=0) {
cout<<"Enter column number of your move";
cin>>columnnum;
if (columnnum<=s.cols()) {
return columnnum;
}
cout<<"Column number not valid ";
}
return -1; //OK?
}
int BadPlayerImpl::chooseMove(const Scaffold& s, int N, int color)
{
if ((N>=s.cols()&&N>=s.levels())||N<=0) { //make sure this works
cout<<"Enter a number within the valid range of columns you specified";
return -1;
}
for (int j=0; j<s.cols();j++) {
if (s.checkerAt(j,0)==VACANT) {
return j;
}
}
return -1; //see if this OK
}
int SmartPlayerImpl::chooseMove(const Scaffold& s, int N, int color)
{
return -1; // This is not always correct; it's just here to compile
}
//******************** Player derived class functions *************************
// These functions simply delegate to the Impl classes' functions.
// You probably don't want to change any of this code.
HumanPlayer::HumanPlayer(string nm)
: Player(nm)
{
m_impl = new HumanPlayerImpl; //error is here
}
HumanPlayer::~HumanPlayer()
{
delete m_impl;
}
int HumanPlayer::chooseMove(const Scaffold& s, int N, int color)
{
return m_impl->chooseMove(s, N, color);
}
BadPlayer::BadPlayer(string nm)
: Player(nm)
{
m_impl = new BadPlayerImpl; //error is here
}
BadPlayer::~BadPlayer()
{
delete m_impl;
}
int BadPlayer::chooseMove(const Scaffold& s, int N, int color)
{
return m_impl->chooseMove(s, N, color);
}
SmartPlayer::SmartPlayer(string nm)
: Player(nm)
{
m_impl = new SmartPlayerImpl; //error is here
}
SmartPlayer::~SmartPlayer()
{
delete m_impl;
}
int SmartPlayer::chooseMove(const Scaffold& s, int N, int color)
{
return m_impl->chooseMove(s, N, color);
}
Below is my declaration of the class Player which is the base class:
class Player
{
public:
Player(std::string nm) : m_name(nm) {}
virtual ~Player() {};
std::string name() const { return m_name; };
virtual bool isInteractive() const { return false; }
virtual int chooseMove(const Scaffold& s, int N, int color) = 0;
// We prevent any kind of Player object from being copied or assigned by
// making the copy constructor and assignment operator unavailable in
// the base class (and thus in any derived class).
Player(const Player& other) = delete;
Player& operator=(const Player& other) = delete;
private:
std::string m_name;
};
Because you declared a constructor in your base class, in particular Player::Player(std::string nm), it's impossible for the compiler to provide an implicit default constructor for your child class as your parent class Player can't be default constructed in the first place.
Either provide a constructor in your child class or inherit the constructor of your base class (C++11). E.g:
BadPlayerImpl::BadPlayerImpl(std:string nm)
: Player(nm)
{
...
}
This is most likely because somewhere in your code you are copy-constructing, or assigning to, an instance of BadPlayerImpl, and you explicitly deleted the copy constructor and the assignment operator of its superclass.
A default constructor is normally automatically created for a class, but there are rules about when it is not created (like when you create another constructor). Where you have "//error is here" you're calling the default constructor of a Sub-Class which will call the (in this case, non-existent) default constructor of the Base-Class.
How can I make a class, which is sometimes readonly, and sometimes writable? One option is with getter/setters and a flag which indicates if the object is read-only, but that is a lot of overhead. I also desire this readonly property to work deeply on the object, making sure that all of the objects it contains are also readonly or writeable. Here's some example code of the desired behavior which I tried but failed to achieve using const.
This question is quite generic, so has probably been asked before, but I wasn't able to find a good solution to this exact problem on stackoverflow.
Example code:
https://ideone.com/4cXyNF
class InnerClass {
public:
InnerClass(int j) : j_(j) {}
int j_;
};
class OuterClass {
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c), pointer_(&c) {}
int i_;
InnerClass& reference_;
InnerClass* pointer_;
};
int main() {
InnerClass c(1);
OuterClass readwrite(2, c);
// Desire these 3 operations to work on the writable object
readwrite.i_ = 3;
readwrite.reference_.j_ = 4;
readwrite.pointer_->j_ = 5;
const OuterClass readonly(6, c);
// COMPILER ERROR: error: assignment of member 'OuterClass::i_'
// in read-only object
// readonly.i_ = 7;
// Desire this to be a compiler error, but it isn't
readonly.reference_.j_ = 8;
// Desire this to be a compiler error, but it isn't
readonly.pointer_->j_ = 9;
return 0;
}
If you change your members to functions, you can create const overloads of the methods like this
class InnerClass {
public:
explicit
InnerClass(int j) : j_(j) {}
int& j() { return j_; }
const int& j() const { return j_; }
private:
int j_;
};
class OuterClass {
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c), pointer_(&c) {}
int& i() { return i_; }
const int& i() const { return i_; }
InnerClass const& reference() const { return reference_; };
InnerClass & reference() { return reference_; };
InnerClass const* pointer() const { return pointer_; };
InnerClass * pointer() { return pointer_; };
private:
int i_;
InnerClass& reference_;
InnerClass* pointer_;
};
int main() {
InnerClass c(1);
OuterClass readwrite(2, c);
// Desire these 3 operations to work on the writable object
readwrite.i() = 3;
readwrite.reference().j() = 4;
readwrite.pointer()->j() = 5;
const OuterClass readonly(6, c);
// COMPILER ERROR: error: assignment of member 'OuterClass::i_'
// in read-only object
readonly.i_ = 7;
// Desire this to be a compiler error, and it is
readonly.reference().j() = 8;
// Desire this to be a compiler error, and it is
readonly.pointer()->j() = 9;
return 0;
}
Live on Coliru
You can achieve this by using member functions to return the references / pointers const if the object itself is const.
class InnerClass {
public:
InnerClass(int j) : j_(j) {}
int j_;
};
class OuterClass
{
InnerClass& reference_;
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c) {}
int i_;
InnerClass & in() { return reference_; }
InnerClass const & in() const { return reference_; }
};
Now neither i_ nor in().j_ is writable in case outer is const:
InnerClass i{ 1 };
OuterClass write(2, i);
write.i_ = 3; // works
write.in().j_ = 3; // works
OuterClass const read(2, i);
read.i_ = 3; // error!
read.in().j_ = 3; // error!
This is a similar solution as some else already posted, but uses a slightly different approach:
class InnerClass {
public:
InnerClass(int j) : j_(j) {}
int j_;
};
template<bool readOnly>
class OuterClass{
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c), pointer_(&c) {}
int i_;
typename std::conditional<readOnly,const InnerClass&, InnerClass&>::type reference_;
typename std::conditional<readOnly,const InnerClass* const, InnerClass*>::type pointer_;
};
int main(int argc,char** args){
InnerClass c(1);
OuterClass<true> readonly(12,c);
//readonly.reference_.j_ = 1; //Error "reference_ is read only"
//readonly.pointer_->j_ = 1; //Error "pointer_ is read only"
OuterClass<false> write(12,c);
write.reference_.j_ = 1;
write.pointer_->j_ = 1;
}
Is the following code valid C++? Otherwise, is there a valid way to simultaneously interpret memory as values of different type?
#include <cstdio>
struct Base { int payload; };
struct D1 : Base { void operator()(){ printf("D1: %d\n", payload);} };
struct D2 : Base { void operator()(){ printf("D2: %d\n", payload);} };
int main()
{
D1 d1;
D2& d2 = static_cast<D2&>(static_cast<Base&>(d1));
d1();
d2();
d2.payload = 3;
d1();
d2();
}
In response to #NickoPo: My use case is basically what follows. Imagine that IntBase is not necessarily cheap to copy, that there are many complex algorithms, some of which profit from numbers being prime vs. odd, and others don't:
#include <cassert>
#include <cstdio>
bool is_odd(int value) { return 0 != value % 2; }
bool is_small_prime(int value) { return 2 == value || 3 == value || 5 == value || 7 == value; }
class IntBase
{
public:
explicit IntBase(int value) : m_value(value) {}
int value() const { return m_value; }
protected:
int m_value;
};
class OddInt : public IntBase
{
public:
explicit OddInt(int value) : IntBase(value) { assert(is_odd(m_value)); }
};
class SmallPrimeInt : public IntBase
{
public:
explicit SmallPrimeInt(int value) : IntBase(value) { assert(is_small_prime(m_value)); }
};
bool is_constrainable_to_odd_int(IntBase const& x)
{
return is_odd(x.value());
}
OddInt const& constrain_to_odd_int(IntBase const& x)
{
assert(is_odd(x.value()));
return static_cast<OddInt const&>(x);
}
bool is_constrainable_to_small_prime_int(IntBase const& x)
{
return is_small_prime(x.value());
}
SmallPrimeInt const& constrain_to_small_prime_int(IntBase const& x)
{
assert(is_small_prime(x.value()));
return static_cast<SmallPrimeInt const&>(x);
}
void algorithm(IntBase const&)
{
printf("algoritm(IntBase const&)\n");
}
void algorithm(OddInt const&)
{
printf("algoritm(OddInt const&)\n");
}
void algorithm(SmallPrimeInt const&)
{
printf("algoritm(SmallPrimeInt const&)\n");
}
void test(IntBase const& x)
{
if (is_constrainable_to_small_prime_int(x))
{
algorithm(constrain_to_small_prime_int(x));
}
else if (is_constrainable_to_odd_int(x))
{
algorithm(constrain_to_odd_int(x));
}
else
{
algorithm(x);
}
}
void test(OddInt const& x)
{
if (is_constrainable_to_small_prime_int(x))
{
algorithm(constrain_to_small_prime_int(x));
}
else
{
algorithm(constrain_to_odd_int(x));
}
}
int main()
{
IntBase x(0);
OddInt y(1);
OddInt z(7);
test(x); // algoritm(IntBase const&)
test(y); // algoritm(OddInt const&)
test(z); // algoritm(SmallPrimeInt const&)
}
Related:
Can I legally reinterpret_cast between layout-compatible standard-layout types?
Answer to Safety of casting between pointers of two identical classes?
If you're going to cast while using similar interfaces while using type as a guarantee, I'd recommend that you just wrap the inner data with your new object type and then provide access to the inner data in order to transfer it from one type to another. There's no point in doing static casting or reinterpret casting if you're not going to do it safely.
Here's an example:
http://coliru.stacked-crooked.com/a/40d5efeff22fcdcd
#include <iostream>
//Base data structure to encapsulate only data.
struct data {
data(int i) : i(i) {}
int i;
};
//Wrapper around our data structure, with interfaces to access
//the values and the data; implement your own constructor to
//gate the value
class PrimeInt {
public:
PrimeInt(const int i)
: d(i) {}
PrimeInt(const data& other)
: d(other) {}
PrimeInt(data&& other)
: d(std::move(other)) {}
PrimeInt& operator=(const PrimeInt&) = default;
PrimeInt& operator=(PrimeInt&&) = default;
int get() {return d.i;};
operator data() {return d;};
private:
data d;
};
//Wrapper around our data structure, with interfaces to access
//the values and the data; implement your own constructor to
//gate the value
class OddInt {
public:
OddInt(const int i)
: d(i) {}
OddInt(const data& other)
: d(other) {}
OddInt(data&& other)
: d(std::move(other)) {}
OddInt& operator=(const OddInt&) = default;
OddInt& operator=(OddInt&&) = default;
int get() {return d.i;};
operator data() {return d;};
private:
data d;
};
//Notice that we can now implicitly cast from one type to another.
int main() {
PrimeInt pi(10);
std::cout << pi.get() << std::endl;
OddInt oi(pi);
std::cout << oi.get() << std::endl;
return 0;
}
If your objects are not cheap to copy, you are probably passing pointers or references everywhere. You can wrap pointers to your common base in different class types and pass them by value. That is, instead of this (pseudocode)
class B
class D1 : B { ... }
class D2 : B { ... }
D1* d1; D2* d2;
you have
class Bimpl
class B { Bimpl* bimpl; }
class D1 : B { ... }
class D2 : B { ... }
D1 d1; D2 d2;
Here you never do any built-in cast. If you want to convert D1 to D2, you write your own conversion function.
In C++11, I'd like to have a member variable in a class and a constructor for its initialization only if its default template value was chosen (only for supported types like int, of course).
What are recommended ways to achieve this (boost allowed)?
Something like:
template< int _x = -1 > struct C {
C() {} // only available if _x != -1
C( int x ) : x( x ) {} // only available if _x == -1
// more methods that are common for all _x and refer to _x / x
private:
int x; // only available if _x == -1
// more members that are common for all _x
};
Or, put in another way: For size and speed optimization, I would like to use a compile time constant instead of a value stored in a member variable if another value than the template default was chosen.
--
Here is an example to make everything clearer:
template< int _size = -1 > struct Block {
Block() { buf = mmap( _size, ... ); } // exists only when size!=-1
Block( int s ) { buf = mmap( size = s, ... ); } // exists only when size==-1
~Block() { munmap( buf, getSize() ); } // should use the correct size
int getSize() const { return ???; } // gets _size if !=-1, size otherwise
// other methods that use buf and getSize()
private:
void *buf;
const int size; // only exists for size == -1!
};
This solves it partially:
template< int _x > struct X {
int getX() const { return _x; }
};
template<> struct X< -1 > {
X( x ) : x( x ) {}
int getX() const { return _x; }
private:
int x;
};
template< int _x = -1 > struct C : X< _x > {
C() {} // only available if _x != -1
C( int x ) : X< _x >( x ) {} // only available if _x == -1
// more methods that are common for all _x and use this->getX()
};
But what about the constructors of C, and are other / nicer solutions available?
Just an idea, but maybe it helps: You could try to use a base class only for the minimal differences and "fake" the member variable for when it's not there to allow the rest to compile:
template< int _x > class B
{
public:
B() {}
protected:
static const int x = _x;
};
template<> class B< -1 >
{
public:
B( int i ) : x( i ) {}
protected:
int x;
};
template< int _x = -1 >
class C : public B<_x>
{
public:
using B<_x>::B; // inherit B's ctors
void f()
{
if ( x == ... ) // uses either the member variable x or the static const int x!
}
};
but as I said, it's just an idea...
Specialization is the way to go:
template <int N> struct C
{
C(int n) : n_(n) { }
int n;
};
template <> struct C<-1>
{
C() { }
C(int n) : n_(n) { }
int n;
};
I'm with Kerrek SB on this one. Put your common code, namely the runtime buffer handling in a common base class an create two derived classes, one for your statically sized buffer class and one for your dynamic buffer class. Or better yet, according to common coding guidelines, use composition.
class buffer_impl {
public:
buffer_impl(int size) : data_ {mmap( size, ... )}, size_ {size} {}
~buffer_impl() { munmap( data_, getSize() ); }
int getSize() const noexcept { return size_; }
// other buffer routines
// ...
private:
void* data_;
int size_;
};
template <int _size = -1 >
class buffer { // static size
public:
buffer() : impl_ {_size} {}
static constexpr int getSize() noexcept { return _size; }
private:
buffer_impl impl_;
};
template <>
class buffer<-1> { // dynamic size
public:
buffer(int size) : impl_ {size} {}
int getSize() const noexcept { return impl_.getSize(); }
private:
buffer_impl impl_;
};