c++ class constant of its own class - c++

Basically, I would like to declare constants of a class within the class itself:
class MyClass {
int itsValue;
public:
MyClass( int anInt) : itsValue( anInt) {}
static const MyClass CLASSCONST;
};
So I can access it like this;
MyClass myVar = MyClass::CLASSCONST;
But I can't find a way to initialize MyClass::CLASSCONST. It should be initilized inside the MyClass declaration, but at that point the constructor is not known. Any one knowing the trick or is it impossible in c++.

class MyClass {
int itsValue;
public:
MyClass( int anInt) : itsValue( anInt) {}
static const MyClass CLASSCONST;
};
const MyClass MyClass::CLASSCONST(42);

Here is a working example with definition outside the class.
The class declaration has a const static member which is initialized outside the class as it is a static member and of type non-integral. So initialization inside the class itself is not possible.
#include <iostream>
class test
{
int member ;
public:
test(int m) : member{m} {}
const static test ob ;
friend std::ostream& operator<<(std::ostream& o, const test& t)
{
o << t.member ;
return o;
}
};
const test test::ob{2};
int main()
{
std::cout << test::ob ;
}

Related

Static const member initialization outside class

how can i initialize static const int member outside class ?
class C
{
public:
C();
private:
static const int a;
static const std::string b;
};
// const int C::a = 4; // i know it
// const std::string C::b = "ba"; // this one too
I'd go with C++17 and use inline static object:
class C
{
public:
C() = default;
private:
inline static const int a = 42;
inline static const std::string b{"foo"};
};
Easiest, cleaniest, most readable.
This is how to initialize static class members outside of the class:
C.cpp
#include <string>
class C {
public:
C();
private:
static const int a;
static const std::string b;
};
C::C() = default;
const int C::a = 4;
const std::string C::b = "ba";
There is no other option to initialize a static class member outside of the class, other than all the various C++ ways to do initialization as variations on this same theme.

Limit the number of object to 1 which can access static member using dot operator

class Test{
public:
static int i;
};
int Test::i=0;
if I make 3 objects of Test t1, t2, t3. Is this possible to achieve that only t1 can access i using dot operator?
You can't overload dot operator, so no, brief answer is that you can't do what you're asking for. You can "hide" the field behind getter\setter and implement them so, probably making class a template with bool flag as a parameter, and do specialization.
// This is NOT working example
template <bool _bFlag> class Test
{
protected:
static int i;
public:
int geti() { return I;}
};
template <> class Test<true>
{
protected:
static int i;
public:
int geti() { return i;}
};
template <> class Test<false>
{
protected:
static int i;
int geti() { return i;} // inaccessible from outside
};
Ok, here is problem.. different specialization will be different classes, they will have different static members. So we should declare base class.
class TestBase
{
protected:
static int i;
};
template <bool _bFlag> class Test : public TestBase
{
public:
int geti() { return i;}
};
template <> class Test<true> : public TestBase
{
public:
int geti() { return i;}
};
template <> class Test<false> : public TestBase
{
protected:
int geti() { return i;} // inaccessible from outside
};
int main()
{
Test<true> t1;
Test<false> t2, t3;
//int i = t2.geti(); // error
}
Does this fluff really cost the time to design this (and the hide of author, when it will be removed by reviewer of code)?
No, there is no way to do this. A static variable exists independent of objects and when it is public, everybody can access it.
int x = Test::i; // <- no object of Test needed at all to access i
What do you really want to achieve? If you want to have a member variable that can be accessed by only a single instance, this is quite possible, but making that variable static is the wrong direction to go.

Calling a getter from another class in a class

I was wondering how you would call a getter function from another class in another class. For example what I have right now is not working
class A{
public:
friend class B;
std::string getfirst(){ return b.getfirst();}
private:
B b;
};
class B{
public:
std::string getfirst(){
return first_;
}
private:
std::string first_;
};
How would I fix this so that I can call B's getfirst function?
You do not need friendship.
What about?
class B {
public:
std::string get_first() const { return first_; }
private:
std::string first_;
};
class A {
public:
std::string get_first() const { return b.get_first(); }
private:
B b;
};
Now, class B has a getter for its first and class A has getter that delegates to b member variable.
class B{
public:
std::string getfirst(){
return first_;
}
private:
std::string first_;
};
class A : public B{
public:
//class A has derived the "getfirst" from B
private:
// add your stuff here
};
did not compile it,but should work fine
The code you have has an error: std::string getfirst(){ is repeated twice in B, this will cause a compilation error.
Also, you do not need to declare B as friend of A, as B is not trying to access any of A's private members. Ignore this if you have a larger code where you do need the friend declaration.
You need to define class B before using using it in A. As B does not access A, you can just put its definition before A's.
This is really wierd
std::string getfirst(){
std::string getfirst(){
return first_; //cause compilation error
It may correct as:
#include <iostream>
using namespace std;
class B; // Forward declaration of class B in order for example to compile
class A
{
public:
string getfirst();
friend string :: getfirst(); // declaration of global friend
};
class B
{
public:
friend string :: getfirst(); // declaration of global friend
friend string A::getfirst(); // declaration of friend from other class
};
I am giving skeleton only.

How to hide a datum from everyone but class T

I want a type A that will yield its hidden datum to an object of type T but hide the datum from everyone else. My C++ compiler happens to be GCC 4.4, but that shouldn't matter. Why won't this work?
#include <iostream>
template <class T> class A {
private:
int n1;
public:
friend class T;
A(const int n0 = 0) : n1(n0) {}
};
class B {
public:
int f(const A<B> a) const { return a.n1; }
B() {}
};
int main() {
const A<B> a(5);
const B b;
const int m = b.f(a);
std::cout << m << "\n";
return 0;
}
Incidentally, this works fine, except that it fails to hide the datum:
#include <iostream>
template <class T> class A {
private:
int n1;
public:
int n() const { return n1; }
A(const int n0 = 0) : n1(n0) {}
};
class B {
public:
int f(const A<B> a) const { return a.n(); }
B() {}
};
int main() {
const A<B> a(5);
const B b;
const int m = b.f(a);
std::cout << m << "\n";
return 0;
}
Does C++ really not allow a friend class to be specified at compile time as a template parameter? Why not? If not, then what alternate technique should I use to hide the datum? (One would prefer a compile-time technique if possible.)
What is my misunderstanding here, please?
(I see some answers to related questions here and here, but either they don't answer my particular question or I fail to understand that they do so. At any rate, maybe I am using the wrong technique altogether. Though I remain interested in why the friend class T fails, what I really want to know is how to hide the datum, whether with a friend or by other means.)
Thanks.
Your compiler is simply too old. C++11 allows you to declare template parameters as friends.
ยง11.3 [class.friend] p3
A friend declaration that does not declare a function shall have one of the following forms:
friend elaborated-type-specifier ;
friend simple-type-specifier ;
friend typename-specifier ;
If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, the friend declaration is ignored.
And it even contains an example of a template parameter as a friend:
class C;
// [...]
template <typename T> class R {
friend T;
};
R<C> rc; // class C is a friend of R<C>
R<int> ri; // OK: "friend int;" is ignored
C++03 sadly has no way to do this, however you can simply friend a single free function and let that act as "glue" code that takes the data from one class and passes it to the other. Another way might be the passkey pattern.
I don't know the standardese behind your error (refer to Xeo's answer), but I did find a workaround for C++03.
Instead of making T a friend, make one of T's member functions a friend:
#include <iostream>
template <class T> class A {
private:
int n1;
public:
friend int T::getN1(const A& a) const;
A(const int n0 = 0) : n1(n0) {}
};
class B {
public:
int f(const A<B> a) const { return getN1(a); }
B() {}
private:
int getN1(const A<B>& a) const {return a.n1;}
};
class C {
public:
int f(const A<B> a) const { return getN1(a); }
C() {}
private:
// Error, n1 is a private member of A<B>
int getN1(const A<B>& a) const {return a.n1;}
};
int main() {
const A<B> a(5);
const B b;
const int m = b.f(a);
std::cout << m << "\n";
return 0;
}
Alternatively, you can make a nested class/struct of T be a friend of A. This may be more convenient if there are several private members of A that you want T to have access to.
#include <iostream>
template <class T> class A {
private:
int n1;
public:
friend class T::AccessToA;
A(const int n0 = 0) : n1(n0) {}
};
class B {
public:
int f(const A<B> a) const { return AccessToA::getN1(a); }
B() {};
private:
friend class A<B>;
struct AccessToA
{
static int getN1(const A<B>& a) {return a.n1;}
};
};
class C {
public:
int f(const A<B> a) const { return AccessToA::getN1(a); }
C() {};
private:
friend class A<C>;
struct AccessToA
{
// Error, n1 is a private member of A<B>
static int getN1(const A<B>& a) {return a.n1;}
};
};
int main() {
const A<B> a(5);
const B b;
const int m = b.f(a);
std::cout << m << "\n";
return 0;
}

Can i declare member variable as const in class of c++?if yes,how?

Can i declare member variable as const in class of c++?if yes,how?
You can - you put const in front of the type name.
class C
{
const int x;
public:
C() : x (5) { }
};
You declare it as you would if it wasn't a member. Note that declaring a variable as const will have considerable effects on the way that the class is used. You will definitely need a constructor to initialise it:
class A {
public:
A( int x ) : cvar( x ) {}
private:
const int cvar;
};
Sure, the simplest way is like this if the value will be the same across all instances of your class:
class X
{
public:
static const int i = 1;
};
Or if you don't want it static:
class X
{
public:
const int i;
X(int the_i) : i(the_i)
{
}
};