I get this:
This is a sample code of the two classes:
main.h
class CControl
{
protected:
int m_X;
int m_Y;
public:
void SetX( int X ) { m_X = X; }
void SetY( int Y ) { m_Y = Y; }
int GetX() { return m_X; }
int GetY() { return m_Y; }
CControl *m_ChildControls;
CControl *m_NextSibling;
CControl *m_PreviousSibling;
CControl *m_Parent;
CControl *m_FocusControl;
};
class CButton : public CControl
{
protected:
bool m_Type;
bool m_Selected;
bool m_Focused;
public:
CButton( bool Type );
~CButton();
};
CButton::CButton( bool Type )
{
}
This is just the declarations of the two classes (they're not complete, but the problem comes in also in the full coded version).
main.cpp
#include <windows.h>
#include "main.h"
int main()
{
CButton *g_Button;
g_Button = new CButton( 1 );
return 0;
}
This is just the application main func where I declare g_Button as a new CButton object for making a debugging analysis.
Are you referring to the CControl * members? Since you didn't initialize them in the constructor it's normal that they are at some "random" value; in particular, the value you see is the pattern used in debug builds in VC++ to mark uninitialized memory.
The same holds also for the other fields of your class (-842150451 is the 32-bit signed integer interpretation of 0xcdcdcdcd).
The pointers could be anything, because they're not initialized.
The compiler generated default constructor for CControl doesn't initialize POD members. You'd need to write your own:
CControl() : m_ChildControls(NULL), m_NextSibling(NULL), m_PreviousSibling(NULL)
m_Parent(NULL), m_FocusControl(NULL)
{
}
You need to initialize the data members of the class in the constructor.
CButton::CButton( bool Type )
{
m_Type = Type;
m_X = m_Y = 0;
m_ChildControls = NULL;
// ...
}
Related
I'm trying to allow a class to implement an interface, where the interface is templated to either allow an update internally or not. The code looks like this and works if the implementation is within the class declaration. If it is moved out (as shown here), I get a compiler error on Visual Studio 2019, and I can't understand why. All help is appreciated!
The following code will not compile. If the out of class implementation and headers are modified to just use the code I commented out, it compiles and works as expected.
#include <atomic>
#include <cstdint>
#include <memory>
#include <iostream>
#include <string>
enum class EntryType { Read, ReadUpdate };
template <EntryType Type>
class IXQ
{
public:
virtual float GetValue() = 0;
};
class X : public IXQ<EntryType::Read>, public IXQ<EntryType::ReadUpdate>
{
public:
float IXQ<EntryType::Read>::GetValue();
/*
float IXQ<EntryType::Read>::GetValue()
{
return _x;
}
*/
float IXQ<EntryType::ReadUpdate>::GetValue();
/*
float IXQ<EntryType::ReadUpdate>::GetValue() {
_counter++;
return _x;
}
*/
float _x = 10.0F;
std::atomic<std::int32_t> _counter = 0;
};
float X::IXQ<EntryType::Read>::GetValue()
{
return _x;
}
float X::IXQ<EntryType::ReadUpdate>::GetValue()
{
_counter++;
return _x;
};
int main(int argc, char* argv[])
{
{
auto k = std::make_unique<X>();
auto ptrQ = static_cast<IXQ<EntryType::Read>*>(k.get());
std::cout << std::to_string(ptrQ->GetValue()) << std::endl;
std::cout << k->_counter.load() << std::endl;
}
{
auto k = std::make_unique<X>();
auto ptrQ = static_cast<IXQ<EntryType::ReadUpdate>*>(k.get());
std::cout << std::to_string(ptrQ->GetValue()) << std::endl;
std::cout << k->_counter.load() << std::endl;
}
return 0;
}
1. Microsoft-specific syntax
The syntax you're using to override GetValue() is not standard c++.
class X : public IXQ<EntryType::Read> {
public:
float IXQ<EntryType::Read>::GetValue() { /* ... */ }
}
This is a Microsoft-Specific Extension for C++ called Explicit Overrides (C++) and is intended to be used with __interfaces (also a microsoft-specific extension to c++).
__interfaces do not officially support c++ templates due to them being intended mostly for COM Interfaces, e.g.:
[ object, uuid("00000000-0000-0000-0000-000000000001"), library_block ]
__interface ISomething {
// properties
[ id(0) ] int iInt;
[ id(5) ] BSTR bStr;
// functions
void DoSomething();
};
It's suprising that float IXQ<EntryType::Read>::GetValue() { /* ... */ } works at all.
2. Standard C++-compliant solutions
In standard C++ the overriden function is determined by the name & arguments alone, so your only option is to override both of them.
e.g.:
class X : public IXQ<EntryType::Read>, public IXQ<EntryType::ReadUpdate>
{
public:
// will be the implementation for both IXQ<EntryType::Read> & IXQ<EntryType::ReadUpdate>
float GetValue() override;
};
float X::GetValue() {
/* ... */
}
Another standard-compliant way would be to create 2 classes that inherit from the given interfaces & then let X inherit from both of them:
class XRead : public IXQ<EntryType::Read> {
public:
float GetValue() override { /* ... */ }
};
class XReadUpdate : public IXQ<EntryType::ReadUpdate> {
public:
float GetValue() override { /* ... */ }
};
class X : public XRead, public XReadUpdate {
/* ... */
};
If you want to share state between XRead & XReadUpdate, you'd have to introduce another level, e.g.:
class XBase {
public:
virtual ~XBase() = default;
protected:
float value;
};
class XRead : public virtual XBase, public IXQ<EntryType::Read> {
float GetValue() override { return value; }
};
class XReadUpdate : public virtual XBase, public IXQ<EntryType::ReadUpdate> {
float GetValue() override { return value; }
};
class X : public XRead, public XReadUpdate {
/* ... */
};
3. Possible recommendations for API Design
Keep in mind though that this type of API design will be rather complicated to use, because you always need to cast to the specific interface first before you can call the function because X{}.GetValue() would be ambigous.
e.g.:
X x;
IXQ<EntryType::Read>& read = x;
std::cout << read.GetValue() << std::endl;
IXQ<EntryType::ReadUpdate>& update = x;
std::cout << update.GetValue() << std::endl;
// this is *not* possible, GetValue() is ambigous
// std::cout << x.GetValue() << std::endl;
I'd recommend separating both interfaces & using different method names, e.g.: godbolt example
struct IXQReadonly {
virtual ~IXQReadonly() = default;
virtual float GetValue() = 0;
};
struct IXQ : IXQReadonly {
virtual float GetValueUpdate() = 0;
};
class X : public IXQ {
public:
X() : value(0.0f), counter(0) { }
float GetValue() override { return value; }
float GetValueUpdate() override {
++counter;
return value;
}
private:
float value;
std::atomic<int> counter;
};
This comes with a whole set of benefits:
You can call GetValue() / GetValueUpdate() directly on X, no need to convert to an interface first
X x;
x.GetValue();
x.GetValueUpdate();
It is immediately clear from the method name if it will update the counter or not
A function that is given an IXQ can call a function that expects IXQReadonly, but not the other way round: (so you can "downgrade" a read-write interface to readonly, but not "upgrade" a readonly interface to read-write)
void bar(IXQReadonly& r) { r.GetValue(); /* we can't do GetValueUpdate() here */ }
void foo(IXQ& x) { bar(x); x.GetValueUpdate(); }
Additionally remember to declare the destructor as virtual (at least in the top-most class / interface), otherwise funny things tend to happen if you try to delete an instance of X through a pointer to one of its bases / interfaces.
I think this can be solved by adding an intermediate layer of classes, let's say X_Read and X_ReadUpdate from which X can inherit.
IXQ
/ \
X_Read X_ReadUpdate
\ /
X
The trick is having those intermediate classes implement GetValue by calling two virtual pure methods, let's say GetValueRead and GetValueReadUpdate respectively. This way, X still inherits from IXQ<EntryType::Read> and IXQ<EntryType::ReadUpdate>, but comes to implement GetValueRead and GetValueReadUpdate, two methods with clear and distinct interfaces.
[Demo]
template <EntryType Type>
class IXQ
{
public:
virtual float GetValue() = 0;
};
class X_Read : public IXQ<EntryType::Read>
{
public:
virtual float GetValue() override { return GetValueRead(); };
virtual float GetValueRead() = 0;
};
class X_ReadUpdate : public IXQ<EntryType::ReadUpdate>
{
public:
virtual float GetValue() override { return GetValueReadUpdate(); };
virtual float GetValueReadUpdate() = 0;
};
class X : public X_Read, public X_ReadUpdate
{
public:
virtual float GetValueRead() override { return _x; }
virtual float GetValueReadUpdate() { _counter++; return _x; };
float _x{10.0f};
std::atomic<std::int32_t> _counter{};
};
// Outputs:
// 10.000000
// 0
// 10.000000
// 1
I have a base product class with a few private members and a public getter that derived classes inherit. I would like to disqualify instantiation, since the class is intended for use with an abstract factory. I thought protected con/destructors might work, however, this breaks my smart pointers. Friending seems like a useful disaster. Is there a well-known solution to this, or should I resign myself to the fact that any client who has the factory injected must also know enough to instantiate the base product?
class Product
{
private:
char type_name;
char size_name;
public:
Product(char, char);
virtual ~Product() {}
void Print();
};
Use a token key.
private:
Product(char, char);
struct key_t{explicit key_t(int){}};
static key_t key(){return key_t(0);}
public:
Product(key_t, char a, char b):Product(a,b){}
static std::shared_ptr<Product> make_shared(char a, char b){ return std::make_shared<Product>(key(),a,b); }
anyone with a Product::key_t can construct a Product without being a friend. And without the key, you cannot.
This lets Product pass creation-rights as a value.
Smart pointers with configurable destroy code can use similar techniques. But I'd just make the destructor public.
Your static member function, or friend function, which is the factory should have no problem with calling protected constructors and returning a smart pointer. Generally plan to return a std::unique_ptr<BaseClass> which can be converted into a std::shared_ptr if the caller wants that instead.
Make the virtual destructor public.
Update: Don't bother making the factory a friend. You only need to prevent the construction of the base and intermediate classes. Make them effectively hidden and private by hiding the implementation classes in their own source file. Or an anonymous namespace I suppose.
Here have some code of how I would do it:
#include <iostream>
#include <memory>
#include <string>
// ITest is the only class any other code file should ever see.
class ITest {
protected:
ITest() = default;
public:
virtual ~ITest() = 0;
virtual int getX() const = 0;
virtual int getY() const = 0;
};
// Destructors must always have an implementation even if they are pure virtual.
ITest::~ITest() {}
std::ostream &operator<<(std::ostream &os, const ITest &x) {
return os << '[' << x.getX() << ',' << x.getY() << ']';
}
// Declaration of constructTest factory function.
// Its definition should be hidden in a cpp file.
std::unique_ptr<ITest> constructTest(int x);
// The main function does not need to know anything except the ITest interface
// class and the constructTest function declaration.
int main(int argc, char *argv[]) {
int val = 0;
if (argc > 1)
val = std::stoi(argv[1]);
auto p = constructTest(val);
std::cout << *p << std::endl;
}
// These classes should be defined in a private header file or in a cpp file.
// Should not be visible to any other code. It has no business knowing.
// Hiding all of this implementation is sort of the point of abstract interface
// classes and factory function declarations.
class TestBase : public ITest {
private:
int x = 0;
int y = 0;
protected:
TestBase(int x = 0, int y = 0) : x(x), y(y){};
public:
int getX() const override { return x; }
int getY() const override { return y; }
};
class TestA final : public TestBase {
public:
TestA() = default;
};
class TestB final : public TestBase {
public:
TestB(int x, int y) : TestBase(x, y) {}
int getX() const override { return -TestBase::getX(); }
};
std::unique_ptr<ITest> constructTest(int x) {
// make_unique is c++14.
// For C++11 use std::unique_ptr<ITest>(new TestB(x, x)
if (x) {
return std::make_unique<TestB>(x, x);
// return std::unique_ptr<ITest>(new TestB(x, x));
}
return std::make_unique<TestA>();
}
The answer was to make the destructor a pure virtual AND to implement it with an empty body. That empty implementation is where I got tripped up. Print() doesn't need to be static.
Product.hpp
#include <memory>
class Product {
public:
virtual ~Product() = 0;
void Print();
protected:
char type_name{};
char size_name{};
private:
};
Product.cpp
#include "Product.hpp"
Product::~Product() {}
void Product::Print() {
//Print p
}
I've currently got code below in which i am trying to initialize the data members x, y and z to 0 when an object of type Solid is being instantiated. The lines 25, 26 and 27 contain errors, how would I rewrite these lines to access the x and y members and set them to 0?
edit 1: I've written out my code below.
edit 2: To clear things up, the only lines of code that can be altered are the lines that contain errors. The derived class should be rewritten to access the private data members.
class Shape
{
private:
int x, y;
protected:
string _type;
public:
Shape() { x = y = 0; }
Shape(int a, int b) { x = a; y = b; }
string type() { return _type; }
void stype(string val) { _type + val; }
int getx() { return x; }
int gety() { return y; }
};
class Solid : public Shape
{
int z;
public:
Solid() { x = y = z = 0; } // errors
Solid(int a, int b, int c) { x = a; y = b; z = c; } //
int Volume() { return x * y * z; } //
};
int main()
{
Solid ob1;
return 0;
}
You can't access private members of a base class, and the point of this exercise is that you don't need to - not that you should come up with a way of doing it.
Your default constructor should only set its own member - Shapes default constructor takes care of its own members:
Solid() { z = 0; }
or (the preferred method, which actually is initialisation and not an assignment)
Solid() :z(0) {}
The other constructor should initialise the base, and then z:
Solid(int a, int b, int c) : Shape(a,b), z(c){}
and Volume should use the provided accessors:
int Volume() { return getx() * gety() * z; }
Inherited class can not access to parent's private attributes. It can access his protected attributes, so you can move your variables to protected. Another option is to use setter function (like getX) and use them.
edit: change only for the relevant errors lines:
Solid():Shape(0,0) { this->z = 0; }
Solid(int a, int b, int c):Shape(a,b) { this->z = c; }
int Volume() { return this->getx() * this->get.y * this->z; }
when you create Solid object, you can also call for the c'tor of Shape with the values you want. That is the right way to initialize values of x, y when creating new inherited objects. For the third line calculation you should use getx() and gety() functions.
As said before, the key is to understand that x and y are not directly accessible for Solid object
You can't, directly, inherit the private members of the parent class. You could use its constructor in your derived class(child class) constructor though-its cool, but I don't use that way. Some information about the access specifiers(the type of inheritance you declare):
Public: Your derived class inherits the protected members of your parent class as protected and the public as public.
Protected: Your derived class inherits the protected members of your parent class as protected and the public as protected.
Private: Your derived class inherits the protected members of your parent class as private and the public as private.
Notice again that the private members of your parent class are not inherited. This should do the trick:
Change:
private:
int x, y;
Into:
protected:
int x, y;
Using the parent class constructor should look like:
class Solid : public Shape
{
private://doesn't matter, just for the aesthetics
int x;
int y;
int z;
public:
Solid() {
Shape();
z = 0; } // errors
And the direct way is(your code with added x,y as properties of the class):
class Solid : public Shape
{
private://doesn't matter, just for the aesthetics
int x;
int y;
int z;
public:
Solid() {x=y=z = 0; } // errors
Private data members are never inherited in any type of inheritance. Hence the name private, but interestingly you can use friend class concept here and even private data members are inherited now,
please try to run the following code:
#include <bits/stdc++.h>
using namespace std;
class Shape
{
private:
int x, y;
protected:
string _type;
public:
Shape() { x = y = 0; }
Shape(int a, int b) { x = a; y = b; }
string type() { return _type; }
void stype(string val) { _type + val; }
int getx() { return x; }
int gety() { return y; }
friend class Solid;
};
class Solid : public Shape
{
int z;
public:
Solid() { x = y = z = 0; } // errors
Solid(int a, int b, int c) { x = a; y = b; z = c; } //
int Volume() { return x * y * z; } //
};
int main()
{
Solid ob1;
return 0;
}
Now you can access x, y in inherited class also, since you declared class solid as friend of shape class.
Hope this answers your question.
as the code below made for example purposes in C #, I would have had to do in C ++, if so how do you do?
public class MyClassTest{
public int testint1{get;set;}
public MyClassTest2 classTest2{get;set;}
}
public class MyClassTest2{
public int testint2{get;set;}
public MyClassTest classTest{get;set;}
}
Something like this.
class MyClassTest {
private: // optional: C++ classes are private by default
int testint1;
public:
int getTestInt1() const { return testint1; }
void setTestInt1(int t) { testint1 = t; }
};
Or you could make your member name distinct and skip the get/set keywords:
class MyClassTest {
private:
int testint1_;
public:
int testint1() const { return testint1_; }
void testint1(int t) { testint1_ = t; }
};
There is no equivalent to this in the current C++ standard, you just have to create getter/setter methods for any fields you want:
class MyClass {
public:
MyClass() {}
// note const specifier indicates method guarantees
// no changes to class instance and noexcept specifier
// tells compiler that this method is no-throw guaranteed
int get_x() const noexcept { return x; }
void set_x(int _x) { x = _x; }
private:
int x;
};
In Visual Studio (mine is 2013), it could be done in this way:
__declspec(property(get = Get, put = Set)) bool Switch;
bool Get() { return m_bSwitch; }
void Set(bool val) { m_bSwitch = val; }
bool m_bSwitch;
in a Class.
I am defining a class GameState and a class MainMenuGameState. The former is meant to be an abstract class and the latter is inheriting it. But somehow, I am not able to overwrite its properties.
GameState.h
#ifndef _GAME_STATE_H_
#define _GAME_STATE_H_
#include <SDL2/SDL.h>
class GameState {
public:
virtual void loop(Uint32 deltaTime) = 0;
virtual void render() = 0;
virtual void event(SDL_Event * event) = 0;
bool stopRenderPropagation = false;
bool stopLoopPropagation = false;
};
#endif
MainMenuGameState.h
#ifndef _MAIN_MENU_GAME_STATE_H_
#define _MAIN_MENU_GAME_STATE_H_
#include "../Game.h"
class MainMenuGameState : public GameState {
public:
MainMenuGameState(Game * pGame);
void loop(Uint32 deltaTime);
void render();
void event(SDL_Event * event);
bool stopRenderPropagation = true;
bool stopLoopPropagation = true;
private:
Game * game;
int xOffset = 0;
int yOffset = 0;
};
#endif
So after instanciating a MainMenuGameState object, I expected stopRenderPropagation and stopLoopPropagation to be true, but they are false.
I also had no luck overwriting them inside the constructor for some reason.
MainMenuGameState::MainMenuGameState(Game * pGame) {
game = pGame;
xOffset = rand() % 20;
yOffset = rand() % 20;
stopRenderPropagation = true;
stopLoopPropagation = true;
}
After that, they are still true. I don't know weather this is a problem with my constructor or if I misunderstood polymorphism in c++.
The instances of MainMenuGameState get stored in a vector<GameState *>, could this be the problem? I am accessing the properties like this:
if(gameStates.begin() != gameStates.end()) {
std::vector<GameState *>::iterator it = gameStates.end();
do {
--it;
} while(it != gameStates.begin() && (*it)->stopLoopPropagation == false);
while(it != gameStates.end()) {
(*it)->loop(deltaTime);
++it;
}
}
Thank you for your help!
Your derived class is declaring another couple of members with the same name of the members in the base class, thus "hiding" the base ones.
You should accept the initial values for those members in the constructor, or if they are fixed properties of the class that never change you should make them member functions instead like in
class GameState {
public:
...
virtual bool stopRenderPropagation() { return false; }
virtual bool stopLoopPropagation() { return false; }
};
class MainMenuGameState : public GameState {
public:
...
bool stopRenderPropagation() { return true; }
bool stopLoopPropagation() { return true; }
...
};
Inheriting data members (your booleans) does not work in the same way as inheriting and overloading methods. Try putting the bools as protected inherited data members instead (uninitialized), and initialize them in the respective subclass constructors instead.
class MainMenuGameState : public GameState {
public:
MainMenuGameState(Game * pGame);
void loop(Uint32 deltaTime);
void render();
void event(SDL_Event * event);
protected:
bool stopRenderPropagation;
bool stopLoopPropagation;
private:
Game * game;
int xOffset = 0;
int yOffset = 0;
};
You declare new variables in your derived class, which is leading to these problems. Variables that are not private are inherited:
struct A { int x };
struct B : A {}; // has B::x by inheritance
You can just set them in your constructor without redeclaration:
struct A { int x; };
struct B : A { B() : x(1) {} };
Notice that it is usually considered bad practice to declare public variables, it is more common to implement getters and setters instead:
struct A
{
int x() const { return x_; }
int & x() { return x_; }
private:
int x_;
};