PDA

Visualizza la versione completa : [c++]stream e errore return type


giuseppe500
14-10-2012, 21:43
ciao.
ho la seguente classe:

.h


class CShaderProgram
{
public:
CShaderProgram();
~CShaderProgram(void);

bool compileShaderFromName( const std::string & strShaderName, GLSLShader::GLSLShaderType type );
char* m_strProgramName;
private:
const char* loadShaderAsString(const char* file);
void printActiveUniforms();
void printActiveAttribs();
int m_handle;//handle del programma compilato
};


.cpp


#include "StdAfx.h"
#include "ShaderProgram.h"
#include "Resources.h"
#include <iostream>
#include <fstream>
CShaderProgram::CShaderProgram()
{
}

CShaderProgram::~CShaderProgram(void)
{
}

const char* CShaderProgram::loadShaderAsString(const char* file){

std::ifstream shader_file(file, std::ifstream::in);
std::string str((std::istreambuf_iterator<char>(shader_file)), std::istreambuf_iterator<char>());

return str.c_str(); //ATTENZIONE PROBLEMA
}

bool CShaderProgram::compileShaderFromName( const string & strShaderName, GLSLShader::GLSLShaderType type )
{
const char* strSource = loadShaderAsString("C:\\OpenResources\\Shaders\\basic.vert");
//non riportato perchè non importante


quando richiamo dall esterno :


CShaderProgram program;
program.compileShaderFromName("basic.vert", GLSLShader::VERTEX);

in:
//ATTENZIONE PROBLEMA
qui :return str.c_str(); col debug vedo che la stringa è caricata correttamente con il contenuto di
C:\\OpenResources\\Shaders\\basic.vert, ma dopo che ritorna str si svuota e il valore const char ritornato è non valido
[0] -18 'î' const char
[1] -2 'þ' const char
e cosi via per tutto il contenuto.
non riesco a capire il perchè!
grazie.

shodan
14-10-2012, 21:52
Se dichiari str all'interno della funzione è normale che all'uscita tu abbia spazzatura.
Piuttosto, c'é qualche ragione per non usare std::string come parametro d'uscita e per m_strProgramName?

giuseppe500
15-10-2012, 11:15
sull str davvero non me n'ero accorto, grazie . poi per quanto riguarda la domanda ti devo confessare che non so mai come alternare l'uso di string e char*, ho delle lacune, ho capito l'uso dei TCHar , unicode ecc.. ma non di std::string, è solo una classe che offre funzionalità aggiuntive all uso dei char* o ci sono delle differenze piu profonde?

intanto grazie per la risposta.
ciao

shodan
15-10-2012, 13:02
Vediamo la cosa da una prospettiva diversa.
In C le stringhe sono array di caratteri NULL terminated (dette anche ASCIIZ). Questo significa che sostanzialmente sono array e vanno trattate come tali. Per dare un minimo supporto alle stringhe ASCIIZ il C mette a disposizione una serie di funzioni di libreria (strcpy per copiare, strcat per concatenare etc.) per poterle manipolare. Queste funzioni però richiedono che chi le usa dia spazio sufficiente alla stringa di destinazione, pena comportamento indefinito, e che in ogni momento del programma sappia esattamente cosa succeda alla sua stringa ASCIIZ. Ne consegue che se tu allochi una stringa ASCIIZ, tu sappia in ogni momento se tale stringa ASCIIZ sia valida, per quanto tempo sia valida, quando deallocarla, non deallocarla due volte ( se no scoppia tutto), sapere se è sufficiente o no per ospitare una sequenza di caratteri e altre cosette che non sto qui a elencare.
Ora uno potrebbe anche dire: ma invece di dovermi preoccupare di tutto questo io personalmente, non posso in C++ crearmi una classe che gestisca tutte le operazione più comuni su una ASCIIZ string del C e risolvere il problema una volta per tutte?
Risposta: SI. PUO'. FARE! (urlato alla Frankesten Junior :D )
Iniziamo quindi a scrivere una classe String prevedendo ogni possibile caso di utilizzo, salvo poi scoprire che esiste una classe che fa le stesse cose (e probabilmente meglio) nella libreria standard del C++ : std::string.
Si scopre così che per copiare una std::string si usa = invece di strcpy() o per concatenarle si usa l'operatore + invece di strcat() e che per fare tutto questo non ci si deve preoccupare di dimensionare a priori la stringa, ma provvede da sola a farlo. Tiene traccia della sua dimensione, quando deallocare le strutture interne e quando no etc.
Detto in parole povere: preferisci lavare i panni a mano o usare una lavatrice?

giuseppe500
15-10-2012, 17:25
un ultima cosa shodan:
uso vs2010, la move semantic è disponibile?

[code]
std::ifstream shader_file(file, std::ifstream::in);
std::string str((std::istreambuf_iterator<char>(shader_file)),
std::istreambuf_iterator<char>());

return str.c_str(); //move semantic
[code]

come potrei utilizzarla?
non è il caso, lo capisco , ma magari metti che il contenuto del file sia enorme.
potrei risolvere con la move semantic?
come?
grazie.

shodan
15-10-2012, 17:58
Originariamente inviato da giuseppe500
un ultima cosa shodan:
uso vs2010, la move semantic è disponibile?

Si.





std::ifstream shader_file(file, std::ifstream::in);
std::string str((std::istreambuf_iterator<char>(shader_file)),
std::istreambuf_iterator<char>());

return str.c_str(); //move semantic


come potrei utilizzarla?
non è il caso, lo capisco , ma magari metti che il contenuto del file sia enorme.
potrei risolvere con la move semantic?
come?
grazie.
Supponendo che il tipo di ritorno sia std::string basta fare.


std::ifstream shader_file(file, std::ifstream::in);
std::string str((std::istreambuf_iterator<char>(shader_file)),
std::istreambuf_iterator<char>());

return std::move(str); //move semantic

giuseppe500
15-10-2012, 18:08
ok.
Ultima cosa non capisco gli R-value , ho letto 200 documentazioni ma non riesco a cpire cosa sono in realtà
e vedo che tutto gira attorno a questa definizione.
senza capirli non riesco a capire la move semantic a fondo.

shodan
15-10-2012, 19:37
Siamo abbondantemente off topic rispetto all'argomento di apertura.
In brevissimo si può dire che il C++11 ha introdotto la move semantics per poter modificare i dati a sinistra di un'espressione (gli rvalue appunto), cosa che prima si poteva fare solo tramite salti mortali e in condizioni particolari.
Nota che per rvalue si intendono anche i temporanei di un'espressione.

Loading