C++ object memory layout when virtual inherit happend? - visual-c++

compiled in VC6
class A
{
public:
int x;
public:
virtual void funA() { }
};
class B : virtual public A
{
public:
int y;
public:
virtual void funA() { }
virtual void funB() { }
};
sizeof(B)=20 // because of B::vptr+vbptr+B::y+A::vptr+A::x = 5*4
class A
{
public:
int x;
public:
virtual void funA() { }
};
class B : virtual public A
{
public:
int y;
public:
B() {}
virtual void funB() { }
};
sizeof(B)=20 // because of B::vptr+vbptr+B::y+A::vptr+A::x = 5*4
class A
{
public:
int x;
public:
virtual void funA() { }
};
class B : virtual public A
{
public:
int y;
public:
B() {}
virtual void funA() { }
virtual void funB() { }
};
sizeof(B)=24
i can't understand , why it's going to be 24???
i think they are the same!

Based on a quick check of the memory after compilation it appears, that a 4 byte block/pad is being added in between the layouts of B and A only when B has a constructor. I'm not sure of the reasoning, but if you are planing to copy memory around, I would recommend against it.
no B::B() // class version 2
const B::'vftable'{for 'B'}
const B::'vbtable'
y
const B::'vftable'{for 'A'}
x
size = 20
including B::B() // class version 3
const B::'vftable'{for 'B'}
const B::'vbtable'
y
0x00000000 // 4 bytes
const B::'vftable'{for 'A'}
x
size = 24

Related

cannot instantiate abstract class & no overloaded function could convert all argument types (c2259 & c2665)

I'm working in visual studio and I keep getting these error.
E0322 object of abstract class type "GameState" is not allowed
Error C2259 'GameState': cannot instantiate abstract class
Error C2665 'GameState::GameState': no overloaded function could convert all the argument types
I understand that I need to override the functions from the state class in the gamestate class and I thought that I did that but apparently not. Can anyone see where I am going wrong?
code:
state.h:
class State {
private:
sf::RenderWindow* window;
std::vector<sf::Texture> textures;
public:
State(sf::RenderWindow* window);
virtual ~State(); //this means that all child classes must define these
virtual void endState() = 0;
virtual void update(const float& dt) = 0;
virtual void render(sf::RenderTarget* target = nullptr) = 0; };
state.cpp
#include "State.h"
State::State(sf::RenderWindow* window)
{
this->State::~State(){}
gamestate.h
#include "State.h"
class GameState :
public State
{
private:
public:
GameState(sf::RenderWindow\* window);
virtual \~GameState();
void endState();
void update(const float& dt);
void render(sf::RenderTarget\* target);
};
Gamestate.cpp
#include "GameState.h"
GameState::GameState(sf::RenderWindow\* window)
: State(window){}
GameState::\~GameState(){}
void GameState::endState(){}
void GameState::update(const float& dt){}
void GameState::render(sf::RenderTarget* target = nullptr){}
game.h
#include "GameState.h"
class Game
{
//variables
sf::RenderWindow* window;
sf::Event sfEvent;
sf::Clock dtClock; //frame tracker
float dt; //deltatime
std::stack<State*> states;
//initialization
void initWindow();
void initStates();
public:
Game();
virtual \~Game();
void updateDeltaTime();
void updateSFMLEvents();
void update();
void render();
void run();
};
game.cpp
//I will be leaving out all the unnecessary code to save space
#include "Game.h"
void Game::initStates() {
this->states.push(new GameState(this->window)); //this is where the problem is
}
hovering over GameState says that State::endState()/render()/update() has no override
please help!!!

How to override error reporting in c++ target of antlr4?

To report errors in a different way in antlr4-java target, we do the following:
(1) define a new listener:
class DescriptiveErrorListener extends BaseErrorListener {
public static DescriptiveErrorListener INSTANCE =
new DescriptiveErrorListener();
#Override
public void syntaxError(Recognizer<?, ?> recognizer,
Object offendingSymbol,
int line, int charPositionInLine,
String msg, RecognitionException e)
{
String printMsg = String.format("ERR: %s:%d:%d: %s",
recognizer.getInputStream().getSourceName(), line,
charPositionInLine+1, msg);
System.err.println(printMsg);
}
}
(2) override the reporter for lexer and parser:
lexer.removeErrorListeners();
lexer.addErrorListener(DescriptiveErrorListener.INSTANCE);
..
parser.removeErrorListeners();
parser.addErrorListener(DescriptiveErrorListener.INSTANCE);
What would be the corresponding code in c++ target?
In C++ it's almost identical (aside from the language specific aspects). Code I use:
struct MySQLParserContextImpl : public MySQLParserContext {
ANTLRInputStream input;
MySQLLexer lexer;
CommonTokenStream tokens;
MySQLParser parser;
LexerErrorListener lexerErrorListener;
ParserErrorListener parserErrorListener;
...
MySQLParserContextImpl(...)
: lexer(&input), tokens(&lexer), parser(&tokens), lexerErrorListener(this), parserErrorListener(this),... {
...
lexer.removeErrorListeners();
lexer.addErrorListener(&lexerErrorListener);
parser.removeParseListeners();
parser.removeErrorListeners();
parser.addErrorListener(&parserErrorListener);
}
...
}
and the listeners:
class LexerErrorListener : public BaseErrorListener {
public:
MySQLParserContextImpl *owner;
LexerErrorListener(MySQLParserContextImpl *aOwner) : owner(aOwner) {}
virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, size_t charPositionInLine,
const std::string &msg, std::exception_ptr e) override;
};
class ParserErrorListener : public BaseErrorListener {
public:
MySQLParserContextImpl *owner;
ParserErrorListener(MySQLParserContextImpl *aOwner) : owner(aOwner) {}
virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, size_t charPositionInLine,
const std::string &msg, std::exception_ptr e) override;
};

How to connect signal from qconcurrent thread to gui thread sharing one string

I'm trying to update gui label with an other thread information (QString).
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public Q_SLOTS:
void sl_appendInfo(QString p_text);
private:
Ui::MainWindow *ui;
QFuture<void> m_thread;
QFuture<void> m_engine;
engine* m_object;
};
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
m_object = new engine();
qRegisterMetaType<QString>();
bool success = connect(this->m_object, SIGNAL(engine::sig_appendInfo(QString)), this, SLOT(sl_appendInfo(QString)), Qt::QueuedConnection);
if(!success)
{
qDebug("success failed");
}
m_engine = QtConcurrent::run(this->m_object, &engine::eventLoop);
}
//slot declaration in mainwindow.cpp
void MainWindow::sl_appendInfo(QString p_text)
{
ui->label->setText(p_text.toLocal8Bit().constData());
}
class engine : public QObject
{
Q_OBJECT
public:
engine();
~engine();
void eventLoop();
Q_SIGNALS:
void sig_exitengine(void);
void sig_appendInfo(QString p_text);
};
void engine::eventLoop()
{
int state = false;
while(true)
{
state = getNextEvent(m_event);
if (state == true)
{
sig_appendInfo("information for gui: we handled a new event !");
state=false;
}
QThread::msleep(1000);
}
}
Now I use this link : My signal / slot connection does not work to build my own code but it didn't work, the connection failed... Can I have some help please?
Thank you
Your connect syntax is wrong. You shouldn't include the class name in the SIGNAL macro. If you use the old syntax, it should be:
bool success = connect(m_object, SIGNAL(sig_appendInfo(QString)), this, SLOT(sl_appendInfo(QString)), Qt::QueuedConnection);
Or if you want to use the new syntax:
bool success = connect(m_object, &engine::sig_appendInfo, this, &MainWindow::sl_appendInfo, Qt::QueuedConnection);

Vala files import

I have a problem when work with properties in separated files in Vala Language
The Main.vala file is
using Teste;
using Cagado;
static int main(string[] args)
{
GUI gui = new GUI();
stdout.printf("%d\n", gui.idade);
return 0;
}
The HelloVala.vala is:
namespace Teste
{
public class Person : Object
{
private int _age = 32;
public int age
{
get { return _age; }
set { _age = value; }
}
}
}
The Cagado.vala is:
using Teste;
namespace Cagado
{
public class GUI : Object
{
Person _person = new Person();
_person.age = 35;
private int _idade;
public int idade
{
get { return _idade; }
set { _idade = value; }
}
}
}
When i compile this code, the compile gives me the message error:
Cagado.vala:9.15-9.15: error: syntax error, expected identifier
_person.age = 35;
^
I program in C# and this not happened in C# oriented object system.
Someone could explain this?
The problem is this:
public class GUI : Object
{
Person _person = new Person();
_person.age = 35; // <--
...
You can't put arbitrary code inside of the class itself, only declarations. What you need to do is something like
public class GUI : Objects
{
Person _person = new Person();
construct {
_person.age = 35;
}
You could also modify add a constructor to the Person class:
namespace Teste
{
public class Person : Object
{
private int _age = 32;
public int age
{
get { return _age; }
set { _age = value; }
}
public Person(int age) {
GLib.Object (age: age);
}
}
}
Then do
public class GUI : Object
{
Person _person = new Person(35);

C++/Cx can't define vertex struct in DirectXBase class, could do it in child classes

Here is my DirectXBase class header:
#pragma once
#include "pch.h"
struct Vertex
{
XMFLOAT3 pos;
XMFLOAT3 color;
};
struct ModelViewProjectionConstantBuffer
{
DirectX::XMFLOAT4X4 model;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
};
ref class DirectXBase abstract
{
internal:
DirectXBase();
virtual void Initialize(
Windows::UI::Core::CoreWindow^ window,
Windows::UI::Xaml::Controls::SwapChainBackgroundPanel^ swapChainPanel,
float dpi);
virtual void HandleDeviceLost();
virtual void CreateDeviceIndependentResources();
virtual void CreateDeviceResources();
virtual void SetDpi(float dpi);
virtual void UpdateForWindowSizeChanged();
virtual void CreateWindowSizeDependentResources();
virtual void Render() = 0;
virtual void Present();
void ValidateDevice();
virtual float ConvertDipsToPixels(float dips);
protected private:
Windows::UI::Core::CoreWindow^ m_window;
Windows::UI::Xaml::Controls::SwapChainBackgroundPanel^ m_swapChainPanel;
// Transforms used for display orientation.
D2D1::Matrix3x2F m_rotationTransform2D;
DirectX::XMFLOAT4X4 m_rotationTransform3D;
DXGI_MODE_ROTATION ComputeDisplayRotation();
//Directx Core Objects
Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice;
Microsoft::WRL::ComPtr<ID3D11DeviceContext1> m_d3dContext;
Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_d3dRenderTargetView;
// Cached renderer properties.
D3D_FEATURE_LEVEL m_featureLevel;
Windows::Foundation::Size m_renderTargetSize;
Windows::Foundation::Rect m_windowBounds;
float m_dpi;
Windows::Graphics::Display::DisplayOrientations m_orientation;
bool m_stereoEnabled;
// Direct3D Rendering Objects. Required for 3D.
Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_d3dDepthStencilView;
// Transform used for display orientation.
DirectX::XMFLOAT4X4 m_orientationTransform3D;
};
I get the following error message:
syntax error : missing ';' before identifier 'pos'
I have no idea why it's not recognizing my struct. The funny thing is, I just copied it and pasted it from the header of a CubeRenderer class that inherits from this one so that I can have access to these structs from any inheriting class...the code ran as copied about five minutes ago.
In case it's helpful, here are my two child class headers with the structs moved to those headers, which compiles and runs fine.
CubeRenderer.h:
#pragma once
#include "DirectXBase.h"
#include <DirectXMath.h>
using namespace DirectX;
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
struct CubeVertex
{
XMFLOAT3 pos;
XMFLOAT3 color;
};
struct CubeMVPBuffer
{
DirectX::XMFLOAT4X4 model;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
};
ref class CubeRenderer : public DirectXBase
{
internal:
CubeRenderer();
virtual void CreateDeviceResources() override;
virtual void CreateWindowSizeDependentResources() override;
virtual void Render() override;
void Update(float timeTotal, float timeDelta);
private:
bool m_loadingComplete;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_constantBuffer;
uint32 m_indexCount;
CubeMVPBuffer m_constantBufferData;
};
HillRenderer.h:
#pragma once
#include "DirectXBase.h"
#include <DirectXMath.h>
using namespace DirectX;
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
struct HillVertex
{
XMFLOAT3 pos;
XMFLOAT3 color;
};
struct HillMVPBuffer
{
DirectX::XMFLOAT4X4 model;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
};
ref class HillRenderer : public DirectXBase
{
internal:
HillRenderer();
virtual void CreateDeviceResources() override;
virtual void CreateWindowSizeDependentResources() override;
virtual void Render() override;
void Update(float timeTotal, float timeDelta);
private:
bool m_loadingComplete;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_constantBuffer;
uint32 m_indexCount;
HillMVPBuffer m_constantBufferData;
float GetHeight(float x, float z) const
{
return 0.3f*(z*sinf(0.1f*x) + x*cosf(0.1f*z));
}
};
Your struct type doesn't "work" is because when you declare that struct, compiler doesn't know (yet) what XMFLOAT3 means.
Before you can use XMFLOAT3 type, it has to be declared somewhere. My guess is it is declared within DirectXMath.h #include DirectXMath.h at the beginning of DirectXBase.h, and it should work.

Resources