C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'



  • Der Zuweisungsoperator von CObject ist private. Offenbar hast du CID3Tag davon abgeleitet, aber den Zuweisungsoperator nicht überschrieben.



  • Wie sieht denn die Klasse CID3Tag aus? Vermutlich ist da etwas drin, womit die Default-Zuweisung nicht zurechtkommt (wenn ich die Fehlermeldung richtig deute, ist der Zuweisungsoperator in der Basisklasse nicht verfügbar).

    Der Fehler selber dürfte in der Methode Add() liegen, wo das Array über operator= den neuen Wert zugewiesen bekommt.



  • Hallo

    Die Klase CID3Tag habe ich aus dem Netz und sie sieht fogendermaßen aus:

    hpp:

    #if !defined(AFX_ID3TAG_H)
    #define AFX_ID3TAG_H
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    class CID3Tag  
    {
    public:
    	// Konstruktor
    	CID3Tag();
    	// Destruktor
    	virtual ~CID3Tag();
    
    	// Daten Gültig 
    	BOOL m_bValide;
    	// ID3 Version 1.0 oder 1.1
    	BOOL m_bIDV10;
    	// Titel
    	CString m_strTitle;
    	// Artist
    	CString m_strArtist;
    	// Album
    	CString m_strAlbum;
    	// Jahr
    	CString m_strYear;
    	// Kommentae
    	CString m_strComment;
    	// Track bei ID3 Version 1.1
    	CString m_strTrack;
    	// Genre
    	CString m_strGenre;
    	// Liste mit gültigen Genre Einträgen
    	CStringList m_lstGenreList;
    
    	// Schreibt ID3 Tag in angegebene Datei
    	int WriteID3Tag(CString FileName);
    	// Liest ID3 Tag aus angegebener Datei
    	int GetID3Tag(CString FileName);
    	// Löscht ID3 Tag aus angegebener Datei
    	int RemoveID3Tag(CString FileName);
    
    private:
    	// Liest Daten aus Datei
    	int GetData(HANDLE hFile);
    	// Schreibt Daten in Buffer
    	int WriteBuf(char *Buf, CString strText, int iOffset, int iCount);
    	// Schreibt Daten in Datei
    	int WriteData(HANDLE hFile);
    	// Initialisiert Genre Liste
    	void FillGenreList();
    	// Ermittelt ID aus Genre
    	char GetGenreID(CString strGenre);
    	// Ermittelt Genre aus ID
    	CString GetGenre(unsigned char uchNumber);
    	// Liest String aus Buffer
    	CString GetString(char *Buff, int Offset, int iCount);
    };
    
    #endif // !defined(AFX_ID3TAG_H)
    

    und die cpp:

    #include "stdafx.h"
    #include "ID3Tag.h"
    
    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif
    
    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    
    CID3Tag::CID3Tag()
    {
    	m_bValide=FALSE;
    	m_bIDV10=TRUE;
    
    	FillGenreList();
    }
    
    CID3Tag::~CID3Tag()
    {
    
    }
    
    /**********************************************************************
    ID3 Tag lesen Funktionen
    **********************************************************************/
    CString CID3Tag::GetString(char *Buff, int Offset, int iCount)
    {
    	char *p;							// Pointer auf Buffer
    	char *strTemp=new char[iCount+1];	// Temp String
    	CString strResult;					// Ergebniss
    
    	// Daten aus Buffer holen
    	p=Buff+Offset;
    	strncpy(strTemp, p, iCount);
    	strTemp[iCount]='\0';
    	strResult=strTemp;
    	strResult.TrimRight(' ');
    
    	free(strTemp);
    	return strResult;
    }
    
    int CID3Tag::GetData(HANDLE hFile)
    {
    	m_bValide=FALSE;	// Daten als nicht Gültig makieren
    
    	if ( hFile == INVALID_HANDLE_VALUE)
    		return -1;	// MP3 konnte nicht geöffnet werden
    
    	char ReadBuf[128];   // LeseBuffer
    	DWORD nBytesRead;   // Anzahl der gelesenen Bytes
    
    	SetFilePointer(hFile, -128, NULL, FILE_END); // Datei Pointer auf ID3Tag setzten
    
    	// ID3Tag lesen
    	ReadFile(hFile, ReadBuf, 128, &nBytesRead, NULL);
    
    	// Keine 128 Bytes gelesen->Fehler
    	if (nBytesRead!=128)
    		return -2;
    
    	// Tag eintrag vorhanden ?
    	if ( (ReadBuf[0]!='T') || (ReadBuf[1]!='A') || (ReadBuf[2]!='G') )
    		return 1;
    
    	// Strings holen
    	m_strTitle=GetString(ReadBuf, 3, 30);
    	m_strArtist=GetString(ReadBuf, 33, 30);
    	m_strAlbum=GetString(ReadBuf, 63, 30);
    	m_strYear=GetString(ReadBuf, 93, 4);
    
    	// Ermitteln ob es sich um Version 1.0 oder 1.1 handelt
    	m_bIDV10 = (ReadBuf[125] != '\0');
    
    	if (m_bIDV10)
    	{	// Version 1.0
    		m_strComment=GetString(ReadBuf, 97, 30);
    		m_strTrack="";
    	} else
    	{	// Version 1.1
    		m_strComment=GetString(ReadBuf, 97, 28);
    		m_strTrack.Format("%u", ReadBuf[126]);
    	}
    
    	// Genre lesen
    	m_strGenre=GetGenre(ReadBuf[127]);
    
    	m_bValide=TRUE;	// Daten als Gültig makieren
    
    	return 0;
    }
    
    /**	Function GetID3Tag
    ***		in : Dateiname der MP3-Datei
    ***		out: Fehlercode	 0 Alles in Ordnung
    ***						 1 ID3Tag nicht vorhanden
    ***						-1 Datei konnte nicht geöffnet werden
    ***						-2 Daten konnten nicht gelsesen werden
    ***/
    int CID3Tag::GetID3Tag(CString FileName)
    {	
    	HANDLE hFile;	// MP3 öffnen
    	hFile = CreateFile(FileName,			// Filename mit Pfad
    				GENERIC_READ,				// Access Mode
    				FILE_SHARE_READ,			// Read sharing 
    				NULL,						// no security attributes
    				OPEN_EXISTING,				// opens existing  
    				FILE_ATTRIBUTE_NORMAL,		// default attributes 
    				NULL);						// no template file 
    
    	int nID=GetData(hFile);
    
    	CloseHandle(hFile); // MP3 Datei schliessen	
    	return nID;
    }
    /**********************************************************************
    Ende ID3 Tag lesen Funktionen
    **********************************************************************/
    
    /**********************************************************************
    ID3 Tag schreiben Funktionen
    **********************************************************************/
    int CID3Tag::WriteBuf(char *Buf, CString strText, int iOffset, int iCount)
    {
    	char *p = Buf+iOffset; // Zeiger auf Buffer Position setzen
    
    	// Daten in Buffer schreiben
    	for (int i=0; i<iCount; i++)
    		if (i<strText.GetLength())
    			p[i]=strText.GetAt(i);
    		else
    			p[i]=0x20;
    
    	return 0;
    }
    
    int CID3Tag::WriteData(HANDLE hFile)
    {
    	m_bValide=FALSE;	// Daten als nicht gultig makieren
    
    	if ( hFile == INVALID_HANDLE_VALUE)
    		return -1;	// MP3 konnte nicht geöffnet werden
    
    	char Buf[128];		 // Lese-/Schreib Buffer
    	DWORD nBytesRead;   // Anzahl der gelesenen Bytes
    	DWORD nBytesWritten;// Anzahl der geschriebenen Bytes
    
    	SetFilePointer(hFile, -128, NULL, FILE_END); // Datei Pointer auf ID3Tag setzten
    
    	ReadFile(hFile, &Buf, 128, &nBytesRead, NULL);
    
    	// Tag eintrag vorhanden ?
    	if ( (Buf[0]!='T') || (Buf[1]!='A') || (Buf[2]!='G') || (nBytesRead!=128) )
    		SetFilePointer(hFile, 0, NULL, FILE_END); // Datei Pointer ans Ende setzten um neuen ID3 Tag zu schreiben
    	else
    		SetFilePointer(hFile, -128, NULL, FILE_END); // sonst Datei Pointer auf ID3Tag setzten
    
    	// Daten in Buffer schreiben
    	WriteBuf(Buf, "TAG", 0, 3);	
    	WriteBuf(Buf, m_strTitle,    3, 30);
    	WriteBuf(Buf, m_strArtist,  33, 30);
    	WriteBuf(Buf, m_strAlbum,   63, 30);
    	WriteBuf(Buf, m_strYear,    93,  4);
    
    	// Version 1.0 oder 1.1 ?
    	if (m_bIDV10)
    		WriteBuf(Buf, m_strComment, 97, 30);
    	else
    	{
    		WriteBuf(Buf, m_strComment,  97, 28);
    		UINT uTemp;
    		sscanf(m_strTrack, "%d", &uTemp);	
    		Buf[125] = '\0';
    		Buf[126] = uTemp;
    	}
    
    	Buf[127]=GetGenreID(m_strGenre);
    
    	// Buffer in Datei schreiben
    	WriteFile(hFile, &Buf, 128, &nBytesWritten, NULL);
    	if (nBytesWritten!=128)
    		return -2;
    
    	m_bValide=TRUE;		// Daten als Gültig makieren
    	return 0;
    }
    
    /**	Function WriteID3Tag
    ***		in : Dateiname der MP3-Datei
    ***		out: Fehlercode  0 Alles in Ordnung
    ***						-1 Datei konnte nicht geöffnet werden
    ***						-2 Fehler beim schreiben
    ***/
    int CID3Tag::WriteID3Tag(CString FileName)
    {
    	m_bValide=FALSE;
    
    	HANDLE hFile;		// MP3 öffnen
    	hFile = CreateFile(FileName,				// Filename mit Pfad
    				GENERIC_READ | GENERIC_WRITE,	// Access Mode
    				0,								// no sharing 
    				NULL,							// no security attributes
    				OPEN_EXISTING,					// opens existing  
    				FILE_ATTRIBUTE_NORMAL,			// default attributes 
    				NULL);							// no template file 
    
    	int nID=WriteData(hFile);
    	CloseHandle(hFile); // MP3 Datei schliessen	
    	return nID;
    }
    /**********************************************************************
    Ende der ID3 Tag schreiben Funktionen
    **********************************************************************/
    
    /**********************************************************************
    ID3 Tag Remove Funktionen
    **********************************************************************/
    
    /**	Function RemoveID3Tag
    ***		in : Dateiname der MP3-Datei
    ***		out: Fehlercode	 0 Alles in Ordnung
    ***						 1 ID3Tag nicht vorhanden
    ***						-1 Datei konnte nicht geöffnet werden
    ***/
    int CID3Tag::RemoveID3Tag(CString FileName)
    {
    	m_bValide=FALSE;
    
    	HANDLE hFile;		// MP3 öffnen
    	hFile = CreateFile(FileName,				// Filename mit Pfad
    				GENERIC_READ | GENERIC_WRITE,	// Access Mode
    				0,								// no sharing 
    				NULL,							// no security attributes
    				OPEN_EXISTING,					// opens existing  
    				FILE_ATTRIBUTE_NORMAL,			// default attributes 
    				NULL);							// no template file 
    
    	int nID=0;
    
    	if ( hFile == INVALID_HANDLE_VALUE)
    		nID=-1;	// MP3 konnte nicht geöffnet werden
    	else
    	{
    		char Buf[128];		 // Lese-/Schreib Buffer
    		DWORD nBytesRead;   // Anzahl der gelesenen Bytes
    
    		SetFilePointer(hFile, -128, NULL, FILE_END); // Datei Pointer auf ID3Tag setzten
    		ReadFile(hFile, &Buf, 128, &nBytesRead, NULL);
    
    		// Tag eintrag vorhanden ?
    		if ( (Buf[0]!='T') || (Buf[1]!='A') || (Buf[2]!='G') || (nBytesRead!=128) )
    			nID=1;
    		else
    		{
    			SetFilePointer(hFile, -128, NULL, FILE_END); // Datei Pointer auf ID3Tag setzten
    			SetEndOfFile(hFile);		// und abschneiden
    		}
    	}
    
    	CloseHandle(hFile); // MP3 Datei schliessen	
    	return nID;
    }
    /**********************************************************************
    Ende der ID3 Tag Remove Funktionen
    **********************************************************************/
    
    /**********************************************************************
    Genre Funktionen
    **********************************************************************/
    CString CID3Tag::GetGenre(unsigned char uchNumber)
    {
    	// Genre Text aus ID bestimmen
    	CString Temp;
    	POSITION pos;
    	pos=m_lstGenreList.FindIndex(uchNumber); //iNumber);
    
    	if (pos==NULL)
    		return "";
    	else
    		return m_lstGenreList.GetAt(pos);
    }
    
    char CID3Tag::GetGenreID(CString strGenre)
    {
    	// Genre ID aus Text bestimmen
    	POSITION pos;
    	int i=0;
    	pos=m_lstGenreList.GetHeadPosition();
    
    	while ( (i<m_lstGenreList.GetCount()) && (strGenre.CompareNoCase(m_lstGenreList.GetNext(pos))!=0) )
    		i++;
    
    	if (i==m_lstGenreList.GetCount()) i=0xff;
    
    	return i;
    }
    
    void CID3Tag::FillGenreList()
    {
    	// m_lstGenreList mit Daten füllen
    	CString Entries[]={
    	"Blues",					"Classic Rock",		"Country",			"Dance",				"Disco",			"Funk",				"Grunge",
    	"Hip-Hop",					"Jazz",				"Metal",			"New Age",				"Oldies",			"Other",			"Pop",	
    	"R&B",						"Rap",				"Reggae",			"Rock",					"Techno",			"Industrial",		"Alternative",
    	"Ska",						"Death Metal",		"Pranks",			"Soundtrack",			"Euro-Techno",		"Ambient",			"Trip-Hop",
    	"Vocal",					"Jazz+Funk",		"Fusion",			"Trance",				"Classical",		"Instrumental",		"Acid",
    	"House",					"Game",				"Sound Clip",		"Gospel",				"Noise",			"Alt. Rock",		"Bass",
    	"Soul",						"Punk",				"Space",			"Meditative",			"Instrumental Pop",	"Instrumental Rock","Ethnic",
    	"Gothic",					"Darkwave",			"Techno-Industrial","Electronic",			"Pop-Folk",			"Eurodance",		"Dream",
    	"Southern Rock",			"Comedy",			"Cult",				"Gangsta",				"Top 40",			"Christian Rap",	"Pop/Funk",
    	"Jungle",					"Native American",	"Cabaret",			"New Wave",				"Psychadelic",		"Rave",				"Showtunes",
    	"Trailer",					"Lo-Fi",			"Tribal",			"Acid Punk",			"Acid Jazz",		"Polka",			"Retro",
    	"Musical",					"Rock & Roll",		"Hard Rock",		"Folk",					"Folk/Rock",		"National Folk",	"Swing",
    	"Fusion",					"Bebob",			"Latin",			"Revival",				"Celtic",			"Bluegrass",		"Avantgarde",
    	"Gothic Rock",				"Progressive Rock",	"Psychedelic Rock",	"Symphonic Rock",		"Slow Rock",		"Big Band",			"Chorus",
    	"Easy Listening",			"Acoustic",			"Humour",			"Speech",				"Chanson",			"Opera",			"Chamber Music",
    	"Sonata",					"Symphony",			"Booty Bass",		"Primus",				"Porn Groove",		"Satire",			"Slow Jam",
    	"Club",						"Tango",			"Samba",			"Folklore",				"Ballad",			"Power Ballad",		"Rhythmic Soul",
    	"Freestyle",				"Duet",				"Punk Rock",		"Drum Solo",			"A capella",		"Euro-House",		"Dance Hall",
    	"Goa",						"Drum & Bass",		"Club-House",		"Hardcore",				"Terror",			"Indie",			"BritPop",
    	"Negerpunk",				"Polsk Punk",		"Beat",				"Christian Gangsta Rap","Heavy Metal",		"Black Metal",		"Crossover",
    	"Contemporary Christian",	"Christian Rock",	"Merengue",			"Salsa",				"Thrash Metal",		"Anime",			"JPop",
    	"Synthpop"
    	};
    
    	for (int i=0; i<(sizeof(Entries)/sizeof(CString)); i++)
    		m_lstGenreList.AddTail(Entries[i]);
    }
    /**********************************************************************
    Ende Genre Funktionen
    **********************************************************************/
    

    Sorry für den ganzen Code, aber ich wollte euch nichts vorenthalten 😉

    chrische



  • chrische5 schrieb:

    Sorry für den ganzen Code, aber ich wollte euch nichts vorenthalten 😉

    Die Headerdatei hätte hier gereicht.

    Die Klasse hat CStringList-Member. CStringList ist nicht kopierbar, damit sind Objekte dieser Klasse auch nicht kopierbar. Und daher kannst du sie nicht in CArray packen.



  • Hallo

    Blöde Frage, aber sie schließt sich logisch an deine Antwort: was kann man den da machen? Den Copy'tor überschreiben?

    chrische



  • chrische5 schrieb:

    was kann man den da machen? Den Copy'tor überschreiben?

    Ich würde eher CStringArray durch eine Containerklasse ersetzen, die kopiert werden kann, z.B. std::vector.

    Ich weiß ja nicht, wo du diese Klasse gefunden hast, aber so besonders toll ist der Code nicht. In GetString wird Speicher, der mit new geholt wurde, mit free wieder freigegeben. Und dass jede Instanz dieser Klasse eine eigene Genreliste mit sich herumschleppt, ist auch nicht gerade schlau.



  • Hallo

    MFK schrieb:

    chrische5 schrieb:

    was kann man den da machen? Den Copy'tor überschreiben?

    Ich würde eher CStringArray durch eine Containerklasse ersetzen, die kopiert werden kann, z.B. std::vector.

    Das Problem war doch aber CStringList oder habe ich da was falsch verstanden?

    MFK schrieb:

    Ich weiß ja nicht, wo du diese Klasse gefunden hast, aber so besonders toll ist der Code nicht. In GetString wird Speicher, der mit new geholt wurde, mit free wieder freigegeben. Und dass jede Instanz dieser Klasse eine eigene Genreliste mit sich herumschleppt, ist auch nicht gerade schlau.

    Habe ich im Netz gefunden. Ich will ein kleines Programm schreiben und dazu muss IDTags auslesen. Das wollte ich aber nicht selber schreiben und habe eine einfach zu bedienende Klasse gesucht. Hast du einen besseren Tipp?

    chrische



  • chrische5 schrieb:

    Das Problem war doch aber CStringList oder habe ich da was falsch verstanden?

    Nein, mein Fehler. Ich meinte CStringList.

    Habe ich im Netz gefunden. Ich will ein kleines Programm schreiben und dazu muss IDTags auslesen. Das wollte ich aber nicht selber schreiben und habe eine einfach zu bedienende Klasse gesucht. Hast du einen besseren Tipp?

    Wenn du es selbst auch nicht besser hinbekommst, dann nimm den Code. Ich wollte dich nur darauf hinweisen, etwas ordentliches kann ich gerade auch nicht aus dem Ärmel schütteln.



  • Hallo

    MFK schrieb:

    chrische5 schrieb:

    Das Problem war doch aber CStringList oder habe ich da was falsch verstanden?

    Nein, mein Fehler. Ich meinte CStringList.

    Ist std::list kopierbar?

    MFK schrieb:

    Habe ich im Netz gefunden. Ich will ein kleines Programm schreiben und dazu muss IDTags auslesen. Das wollte ich aber nicht selber schreiben und habe eine einfach zu bedienende Klasse gesucht. Hast du einen besseren Tipp?

    Wenn du es selbst auch nicht besser hinbekommst, dann nimm den Code. Ich wollte dich nur darauf hinweisen, etwas ordentliches kann ich gerade auch nicht aus dem Ärmel schütteln.

    Ich will mich gar nicht damit beschäftigen, weil mir das zuviel Stress für mein kleines Programm ist.

    chrische



  • chrische5 schrieb:

    Hallo

    MFK schrieb:

    chrische5 schrieb:

    Das Problem war doch aber CStringList oder habe ich da was falsch verstanden?

    Nein, mein Fehler. Ich meinte CStringList.

    Ist std::list kopierbar?

    Ja, ist es (wie alle STL-Container)



  • Hallo

    Danke. Das habe ich dann selber zu Hause nachgeschlagen. Ich habe es nun komplett anders gelöst und speichere erstmal die Dateinamen in einem CStringArray und arbeite dann nur mit einer Insatnz, die ich immer wieder neue Tags laden lasse.

    chrische


Anmelden zum Antworten