I'm trying to create static constant that will be named the same in different classes and can be accessed from other classes
I'm trying to access to the constant from other classes like that B::num
My code:
main.cpp
...
Ptr ptr;
A *a = C::make(ptr);
A.h
class A { //pure virtual
public:
virtual void func()=0;
virtual void func2()=0;
protected:
Ptr ptr;
}
B.h
class B : public A {
public:
B();
static unsigned char const num[2];
...
}
B.cpp
#include "B.h"
constexpr unsigned char B::num[]={0x4,0x5};
B::B(){..}
C.h
#include "A.h"
#include "B.h"
class C {
public:
static A* make(const Ptr &);
}
C.cpp
A *C::make(const Ptr &ptr){
if(!memcmp(ptr.memory,B::num,sizeof(B::num))){
...
}
}
errors
B.h file - error: from previous declaration 'B::num'
B.cpp file - error: redeclaration B::num differs in 'constexpr'
What is the problem?
Thanks.
First problem : you defined an unrelated, global a. The one you're trying to define is scoped inside the class(es).
static constexpr unsigned char class1::a[2] = {0x4,0x5};
// ^^^^^^^^
Second problem : defintions belong in .cpp files, not headers.
Here is an example of static const a in 2 classes :
#include <iostream>
class class1 {
public:
static unsigned char const a[2];
};
class class2 {
public:
static unsigned char const a[2];
};
constexpr unsigned char class1::a[] = {0x4,0x5};
constexpr unsigned char class2::a[] = {0x4,0x5};
int main() {
std::cout << static_cast<unsigned>(class1::a[0])
<< static_cast<unsigned>(class2::a[1]) << std::endl;
return 0;
}
Note:
the declaration contains static and const and should be in a .h file
the definition constains constexpr and should be in a .cpp
Related
I have the following code:
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
class A {
public:
int f();
int (A::*x)();
};
int A::f() {
return 1;
}
int main() {
A a;
a.x = &A::f;
printf("%d\n",(a.*(a.x))());
}
Where I can initialize the function pointer correctly. But I want to make the function pointer as static, I want to maintain single copy of this across all objects of this class.
When I declare it as static
class A {
public:
int f();
static int (A::*x)();
};
I am unsure of the way/syntax to initialize it to function f. Any resource would be helpful
A static pointer-to-member-function (I guess you already know this is different from a pointer to a static member function) is a kind of static member data, so you have to provide a definition outside the class like you would do with other static member data.
class A
{
public:
int f();
static int (A::*x)();
};
// readable version
using ptr_to_A_memfn = int (A::*)(void);
ptr_to_A_memfn A::x = &A::f;
// single-line version
int (A::* A::x)(void) = &A::f;
int main()
{
A a;
printf("%d\n",(a.*(A::x))());
}
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.
i have a problem to compile the classes with cyclic dependency, and i can not find the way to compile my code
the main problem is appeared in chain of classes that has dependency to each others
for example i have 6 header files(Classes) (A, B, C, D, E, F)
A included in E
F, D included in A
E included in F, D
now i have a loop and cant fix it
i simplify the problem then create the simple example to show what is my exact problem
A.h
#ifndef A_H
#define A_H
#include "B.h"
class A
{
public:
static A& getInstance()
{
static A instance;
return instance;
}
int i;
int sum()
{
return i+B::getInstance().j;
}
private:
A() {}
};
#endif
B.h
#ifndef B_H
#define B_H
#include "A.h"
class B
{
public:
static B& getInstance()
{
static B instance;
return instance;
}
int j;
int sum()
{
return j+A::getInstance().j;
}
private:
B() {}
};
#endif
main.cpp
#include "A.h"
#include "B.h"
#include <iostream>
int main()
{
A::getInstance().i=1;
B::getInstance().j=2;
int t1=A::getInstance().sum();
int t2=B::getInstance().sum();
std::cout<<t1<<std::endl;
std::cout<<t2<<std::endl;
return 0;
}
g++ main.cpp
In file included from A.h:3:0,
from main.cpp:1:
B.h: In member function ‘int B::sum()’:
B.h:17:12: error: ‘A’ has not been declared
return j+A::getInstance().j;
is there any way or solutions to resolve this?
If you can't use .cpp files for some reason, you can do this:
a.h:
#pragma once
class A {
public:
static A& getInstance();
int i;
int sum();
private:
A();
};
a_impl.h:
#pragma once
#include "a.h"
#include "b.h"
inline A& A::getInstance() {
static A instance;
return instance;
}
inline int A::sum() {
return i + B::getInstance().j;
}
inline A::A() {
}
b.h:
#pragma once
class B {
public:
static B& getInstance();
int j;
int sum();
private:
B();
};
b_impl.h:
#pragma once
#include "a.h"
#include "b.h"
inline B& B::getInstance() {
static B instance;
return instance;
}
inline int B::sum() {
return j + A::getInstance().i;
}
inline B::B() {
}
And then first include declarations a.h and b.h, and then implementations a_impl.h and b_impl.h:
#include "a.h"
#include "b.h"
#include "a_impl.h"
#include "b_impl.h"
#include <iostream>
int main() {
A::getInstance().i = 1;
B::getInstance().j = 2;
int t1 = A::getInstance().sum();
int t2 = B::getInstance().sum();
std::cout << t1 << std::endl;
std::cout << t2 << std::endl;
}
Now it will compile. In this particular example, B (or A) could've been implemented inside class definition (so, no b_impl.h). I separated declarations and definitions for both classes for the sake of symmetry.
I have a class A with the following declaration (A.h file):
#ifndef __A_DEFINED__
#define __A_DEFINED__
class A
{
public:
template<typename T> inline void doThat() const;
};
#endif
and a class B deriving from that class (B.h file):
#ifndef __B_DEFINED__
#define __B_DEFINED__
#include <iostream>
#include "A.h"
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
#endif
So far, so good. My issue is that the function A::doThat() uses B::doThis():
template<typename T> inline void A::doThat() const { B b; b.doThis(); }
Usually, the circular dependency would not be an issue because I would just define A::doThat() in the .cpp file. In my case however, doThat is a template function so I can't do that.
Here are the solutions I have envisioned so far:
Defining the template function A::doThat() in a .cpp file. The issue with that is that I need to instantiate explicitly all the calls with various template arguments (there might be many in the real case).
After the declaration of the A class in A.h, add #include "B.h" and then define the A::doThat() function. This works fine in visual studio but g++ does not like it.
Is there a neat way to solve this problem?
EDIT: In the real case, there is not just one child class B, but several (B, C, D, etc.) The function A::doThat() depends on all of them. The function B::doThis() is also templated.
A default template parameter for the B class could work:
#include <iostream>
// include A.h
class B;
class A
{
public:
template<typename T, typename U = B> inline void doThat() const
{
U b; b.doThis();
}
};
// include B.h
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
// main
int main()
{
A a;
a.doThat<int>();
}
Usually the best way to allow a parent to call a child function is to declare the function as a pure virtual function in the parent and override it in the children.
#include <iostream>
class A
{
public:
virtual ~A() = default;
template<typename T> inline void doThat() const
{
// do some other stuff
doThis();
}
virtual void doThis() const = 0; // pure virtual function
};
class B: public A
{
public:
void doThis() const override
{
std::cout << "do this!" << std::endl;
}
};
int main()
{
B b;
A* ap = &b;
ap->doThat<int>();
}
The following does work with g++:
File A.h:
#ifndef __A_DEFINED__
#define __A_DEFINED__
class A
{
public:
template<typename T> inline void doThat() const;
};
#include "B.h"
template<typename T> inline void A::doThat() const { B b; b.doThis(); }
#endif
File B.h:
#include <iostream>
#include "A.h"
// We check for the include guard and set it AFTER the inclusion of A.h
// to make sure that B.h is completely included from A.h again.
// Otherwise the definition of A::doThat() would cause a compiler error
// when a program includes B.h without having included A.h before.
#ifndef __B_DEFINED__
#define __B_DEFINED__
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
#endif
File test_A.cpp:
// In this test case we directly include and use only A.
#include "A.h"
#include "A.h" // We test whether multiple inclusion causes trouble.
int main() {
A a;
a.doThat<int>();
}
File test_B.cpp:
// In this test case we directly include and use only B.
#include "B.h"
#include "B.h" // We test whether multiple inclusion causes trouble.
int main() {
B b;
b.doThat<int>();
b.doThis();
}
Alternative Idea:
I do not know whether you (or some coding conventions) insist on separate header files for each class, but if not the following should work:
You can put the definitions of class A and class B and of the member function template A::doThat<typename>() (in this order) together in one header file AandB.h (or whatever name you like).
This cries for polymorphism. There are two options using polymorphism:
Dynamic polymorphism, i.e. make A an abstract base class and call doThis() virtually:
struct A
{
virtual void do_this() const = 0;
template<typename T>
void doThat() const { doThis(); }
};
struct B : A
{
void doThis() const override { /* ... */ }
};
Of course, this only works if doThis() is not templated. If you need that, you could use
Static polymorphism, i.e. CRTP, when
template<typename Derived>
struct A
{
template<typename T>
void doThat() const { static_cast<const Derived*>(this)->template doThis<T>(); }
};
struct B : A<B>
{
template<typename T>
void doThis() const { /* ... */ }
};
If (as in your example code) B::doThis() is not called for the same object, but for some temporary, you could
template<typename typeB>
struct A
{
template<typename T>
void doThat() const { typeB b; b.template doThis<T>(); }
};
I have header.h
Class A
{
int var_1;
int var_2;
};
Class b
{
private: static A var[MAX];
.....
};
But how can I initialize this property in header.cpp?
Give A a default constructor that sets the ints to 0s or something.
A b::var[MAX] = {};
In implementation file:
A b::var[] = {}; // static member definition
// A() is called for each member so you might want
// to implement it
example:
#define MAX 10
class A
{
int var_1;
int var_2;
};
class b
{
private:
static A var[MAX]; // static member declaration
};
A b::var[] = {}; // static member definition
int main() {
return 0;
}
http://ideone.com/ndkPmX
Assuming there is class A with the public constructor that takes no arguments (or default constructor):
File b.h :
#include "a.h"
// global constant:
const int MAX = 10;
class B {
private:
static A var[MAX]; // declaration
};
File b.cpp :
#include "b.h"
A B::var[MAX] = {}; // definition