Page 1 of 1

A quick question on reference initialisation

Posted: September 26th, 2019, 6:04 pm
by AleksiyCODE
Hey!
So I'm trying to write a game (https://gitlab.com/AleksiyCODE/riftedtimes (not much to look at yet)), but here is a quick question:
when i do in a constructor
class A
{
public:
A(Graphics& in_gfx)
:
gfx(in_gfx) {}; //this line!
privare:
Graphics& gfx;
}

it works, but if i do

class A
{
public:
A(Graphics& in_gfx)
:
{
gfx=in_gfx; //here
};
privare:
Graphics& gfx;
}
it says some shit about deleted functions Image (i can see that rhey are deleted in Graphics.h)
So, I don't really understand what dark magic initializer list uses, and thus can't replicate it.
p.s. i think i can get away with using pointers, but understanding this seems usefull, so thanks for your answers in advance oмo

Re: A quick question on reference initialisation

Posted: September 27th, 2019, 10:58 am
by chili
Did you copy that code or like type it out again. Because privare is not a C++ keyword ;)

Re: A quick question on reference initialisation

Posted: September 27th, 2019, 3:30 pm
by AleksiyCODE
Man, you got me there :( . Here's a copypasted version of initializing Graphics& that works:
class ActionBox
{
public:
ActionBox(const std::wstring & boxSpriteFileName,Surface* iconSprites,
Vec2 in_pos,std::vector<Vec2> in_skillPos, std::vector<char> keyToSkill,
int nBoxSkills,Graphics& in_gfx)
:
boxPos(in_pos),
skillPos(in_skillPos),
keyToSkill(keyToSkill),
//boxPool(pool),
nBoxSkills(nBoxSkills),
pIconSprites(iconSprites),
gfx(in_gfx), //!this ine here
boxSprite(Surface::FromFile(boxSpriteFileName))
{}
protected:
std::vector<Skill*> boxPool;
private:
Vec2 boxPos;
int nBoxSkills;
Surface boxSprite;
Surface* pIconSprites;
std::vector<Skill*> pickedSkills;
Graphics& gfx;
//Pool& boxPool;
std::vector<Vec2> skillPos;
std::vector<char> keyToSkill;
};

and here is the one that doesn't (screenshot from previous message shows the error)

class ActionBox
{
public:
ActionBox(const std::wstring & boxSpriteFileName,Surface* iconSprites,
Vec2 in_pos,std::vector<Vec2> in_skillPos, std::vector<char> keyToSkill,
int nBoxSkills,Graphics& in_gfx)
:
boxPos(in_pos),
skillPos(in_skillPos),
keyToSkill(keyToSkill),
//boxPool(pool),
nBoxSkills(nBoxSkills),
pIconSprites(iconSprites),

boxSprite(Surface::FromFile(boxSpriteFileName))
{
gfx=in_gfx; //here
}
protected:
std::vector<Skill*> boxPool;
private:
Vec2 boxPos;
int nBoxSkills;
Surface boxSprite;
Surface* pIconSprites;
std::vector<Skill*> pickedSkills;
Graphics& gfx;
//Pool& boxPool;
std::vector<Vec2> skillPos;
std::vector<char> keyToSkill;
};

The question is: how else (besides initializer list) can i initialize my Graphics&?

Re: A quick question on reference initialisation

Posted: September 28th, 2019, 11:36 am
by AleksiyCODE
Oh, forgot to mention that Graphics class is the same as in Beginner series, but Ill leave Graphics.h code here just in case
Spoiler:
/******************************************************************************************
* Chili DirectX Framework Version 16.10.01 *
* Graphics.h *
* Copyright 2016 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of The Chili DirectX Framework. *
* *
* The Chili DirectX Framework is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* The Chili DirectX Framework is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with The Chili DirectX Framework. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#pragma once
#include <d3d11.h>
#include <wrl.h>
#include "GDIPlusManager.h"
#include "ChiliException.h"
#include "Surface.h"
#include "Colors.h"
#include "Vec2.h"

#define CHILI_GFX_EXCEPTION( hr,note ) Graphics::Exception( hr,note,_CRT_WIDE(__FILE__),__LINE__ )

class Graphics
{
public:
class Exception : public ChiliException
{
public:
Exception( HRESULT hr,const std::wstring& note,const wchar_t* file,unsigned int line );
std::wstring GetErrorName() const;
std::wstring GetErrorDescription() const;
virtual std::wstring GetFullMessage() const override;
virtual std::wstring GetExceptionType() const override;
private:
HRESULT hr;
};
private:
// vertex format for the framebuffer fullscreen textured quad
struct FSQVertex
{
float x,y,z; // position
float u,v; // texcoords
};
public:
Graphics( class HWNDKey& key );
Graphics( const Graphics& ) = delete;
Graphics& operator=( const Graphics& ) = delete;
void EndFrame();
void BeginFrame();
void DrawLine( const Vec2& p1,const Vec2& p2,Color c )
{
DrawLine( p1.x,p1.y,p2.x,p2.y,c );
}

void DrawLine( float x1,float y1,float x2,float y2,Color c );
void DrawRect(int x0, int y0, int x1, int y1, Color c);
void DrawRect(const Vec2& p1, const Vec2& p2, Color c)
{
DrawRect(p1.x, p1.y, p2.x, p2.y, c);
}
void PutPixel( int x,int y,int r,int g,int b )
{
PutPixel( x,y,{ unsigned char( r ),unsigned char( g ),unsigned char( b ) } );
}
void PutPixel( int x,int y,Color c )
{
sysBuffer.PutPixel( x,y,c );
}
~Graphics();

private:
GDIPlusManager gdipMan;
Microsoft::WRL::ComPtr<IDXGISwapChain> pSwapChain;
Microsoft::WRL::ComPtr<ID3D11Device> pDevice;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> pImmediateContext;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> pRenderTargetView;
Microsoft::WRL::ComPtr<ID3D11Texture2D> pSysBufferTexture;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> pSysBufferTextureView;
Microsoft::WRL::ComPtr<ID3D11PixelShader> pPixelShader;
Microsoft::WRL::ComPtr<ID3D11VertexShader> pVertexShader;
Microsoft::WRL::ComPtr<ID3D11Buffer> pVertexBuffer;
Microsoft::WRL::ComPtr<ID3D11InputLayout> pInputLayout;
Microsoft::WRL::ComPtr<ID3D11SamplerState> pSamplerState;
D3D11_MAPPED_SUBRESOURCE mappedSysBufferTexture;
Surface sysBuffer;

public:
static constexpr unsigned int ScreenWidth = 1920u;
static constexpr unsigned int ScreenHeight = 1080u;
};

Re: A quick question on reference initialisation

Posted: September 28th, 2019, 5:58 pm
by Yumtard
References must know what they're referencing when they are created. This is why they need to go in the initializer list. Stuff that get its value in the body of the constructor are actually first default constructed and then copy assigned.

For this reason it's actually more efficient to initialize objects in the initializer list anyways since it's just a call to the copy constructor instead of both the default constructor and copy assignment.

Here's an experiment you can do

Code: Select all

class Foo
{
	public:
		Foo() = delete;
};

class Bar
{
	public:
		Bar( Foo f )
		//: foo( f ) <- This will compile
		{
			foo = f; // This wont compile
		}
	
	private:
		Foo foo;
}

Re: A quick question on reference initialisation

Posted: September 28th, 2019, 8:01 pm
by AleksiyCODE
Thanks a lot, that fully answers my question!
Now im a step closer to the Almighty C++ Sex God
Spoiler:
Image