Jak odkazovat na nekompletní typ? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak odkazovat na nekompletní typ? – C / C++ – Fórum – Programujte.comJak odkazovat na nekompletní typ? – C / C++ – Fórum – Programujte.com

 

oxidián0
Grafoman
9. 6. 2016   #1
-
0
-

mám modul dft_class_3.cpp

ze kterého inkluduju funkce:

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"

class MyDFT; // forward declaration
void printText(char * text, MyDFT &mydft);


Problém je v tom, že MyDFT ještě nebyl zkompilovaný a ve funkci printText potřebuju odkázat na zatím neexistující funkce:

#include "functions.h"

void printText(char * text, MyDFT &mydft){
	cv::RNG rand(0xFFFFFFFF);
	int xmin, xmax, ymin, ymax;
	xmin = 0; ymin=0;
	int file_no = mydft->file_no;
	xmax = mydft->Images[file_no].cols;
	ymax = mydft->Images[file_no].rows;
	cv::Point point;
	point.x = rand.uniform(xmin,xmax);
	point.y = rand.uniform(ymin,ymax);
	int lineType = 8;
	int thickness = 4;
	int icolor = (unsigned) rand;
	cv::Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
	cv::putText( mydft->Images[file_no], "Oo", point, 8,
		5.1, 
		cv::Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 ), // color
		thickness, lineType);
}

Takže tam kde se snažím nastavit číslo souboru:

int file_no = mydft->file_no;


Tam je chyba  error C2027: use of undefined type 'MyDFT'

Jak z toho ven?

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
9. 6. 2016   #2
-
0
-

Naincludujes header s MyDFT

Mimochodem, kdyz mas parametr: MyDFT & mydft; tak je to reference a pro zmenu musis pouzit . a ne ->, protoze to neni pointer.

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
9. 6. 2016   #3
-
0
-

To je soubor dft_class_3.h, tím se ale kompiluje dft_class_3.cpp kde se používá funkce, která ještě nebyla deklarována, natož zkompilována:

printText("Oo");

Logicky by to nemělo jít zkompilovat a zdá se taky že nejde. Jako by se to zacyklovalo.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
9. 6. 2016   #4
-
0
-
Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
9. 6. 2016   #5
-
0
-

Musi to znat akorat prototyp (rozhrani tridy), .cpp soubory se kompiluji nezavisle, zkompilovanou funkci nebo metodu pak musi mit k dispozici az linker.

Forward deklaraci nepotrebujes, dokud se ti to nezacne cyklit. Kazdopadne se da pouzit i s referenci, ne jen s pointerem. A .cpp soubor uz musi includovat kompletni rozhrani te tridy.

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
9. 6. 2016   #6
-
0
-

Napsal jsem to dle odpovědi na stackoverflow:

#include "process_image.h"

class MyDFT;
class ProcessImage {
	private:
		MyDFT* pFwdMyDFT;
	public:
	void printText(char * text, 
		const  &pFwdMyDFT) const;
}


A nefunguje mi to.

1. nechápu proč je na konci to const

2. s const na konci ale i bez toho mám chybu

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

Proccess_image.h jen includuje knihovny, ještě tam nic není

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
9. 6. 2016   #7
-
0
-

1. const je tam jako oznaceni, ze tato metoda nemeni tridni promenne (a pokud nahodou ano, tak to nezkompilujes). To se vyuziva v pripade, ze ti nekdo objekt napriklad preda jako konstatni referenci do nejake metody nebo funkce. Pak nemuzes pouzit zadnou metodu, ktera meni tridni promenne (tj. muzes pouzit jen to, co je oznacene const).

2. nejak moc nechapes co je datovy typ, co promenna a co je jen obycejny modifikator. Ten const je jen modifikator, ze datovy typ nema byt zmenen. Datovy typ tam zadny nemas, proto se ti to snazi rici, ze v C++ neni "implicitni" datovy typ povolen. No a taky si prekryjes tridni promennou tou stejne pojmenovanou promennou v prototypu metody printText (tedy pokud to zvladnes rozjet). 

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
9. 6. 2016   #8
-
0
-

"Datovy typ tam zadny nemas, proto se ti to snazi rici, ze v C++ neni "implicitni" datovy typ povolen."

Já to opisoval z té jejich odpovědi, takže teď bych měl vlastně hlasovat -1 za nefunkční kód v odpovědi!

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
9. 6. 2016   #9
-
+1
-
Zajímavé

   

A * ptr;
void mymethod(const& A) const;

// neni to same jako:
A * ptr;
void mymethod(const& ptr) const;

// nicmene autor asi chtel:
void mymethod(const A &) const ; // kde jen neurcis, jak se ta promenna jmenuje (tady to neni potreba znat, je to vetsinou jen pro citelnost/pochopitelnost prototypu)
Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
9. 6. 2016   #10
-
0
-

Napsal jsem toto:

process_image.h

#ifdef PROCESS_IMAGE_H
#define PROCESS_IMAGE_H

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"

class MyDFT;
class ProcessImage {
	private:
		MyDFT* refMydft;
	public:
	void printText(char * text, 
		MyDFT &refMydft);
};

#endif

process_image.cpp

#include "process_image.h"
#include "dft_class_3.h"

void ProcessImage::printText(char * text, 
	MyDFT &refMydft){

	cv::RNG rand(0xFFFFFFFF);
	int xmin, xmax, ymin, ymax;
	xmin = 0; ymin=0;
	int file_no = refMydft.getFileNumber();
	xmax = refMydft.Images[file_no].cols;
	ymax = refMydft.Images[file_no].rows;
	cv::Point point;
	point.x = rand.uniform(xmin,xmax);
	point.y = rand.uniform(ymin,ymax);
	int lineType = 8;
	int thickness = 4;
	int icolor = (unsigned) rand;
	/* bitovým shiftem pomocí masky vytvoříme z 32bitového čísla tři 
	barvy a ty předáme do Scalar. Scalar příjme 3xuchar.
	*/
	cv::Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
	cv::putText( refMydft.Images[file_no], "Oo", point, 8,
		5.1, 
		cv::Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 ), // color
		thickness, lineType);

};

Chyby:

process_image.cpp(4): error C2653: 'ProcessImage' : is not a class or namespace name
process_image.cpp(11): error C2248: 'MyDFT::Images' : cannot access private member declared in class 'MyDFT'
dft_class\dft_class_3.h(18) : see declaration of 'MyDFT::Images'
dft_class_3.h(13) : see declaration of 'MyDFT'
1>

To nechápu. Třídu jsem deklaroval.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
9. 6. 2016   #11
-
0
-

Už jsem s tím trochu pohnul, ale zaseklo se to na

dft_class_3.cpp(37): error C2664: 'ProcessImage::printText' : cannot convert parameter 2 from 'MyDFT *const ' to 'MyDFT &'

hlavička třídy MyDFT

#include "process_image.h"

class MyDFT {
	private:
		int file_no;
		int editImage;
		char ** args;
		cv::Mat padded;
		cv::Mat channels;
		cv::Mat complex;
	public: 
		cv::Mat images[2]; // up to two images
		MyDFT(char ** argv);
		int getFileNumber();
		cv::Mat * getImage(int file_no);
		int getSpectrum(const char * file, int flag);
};



process_image.h:

class MyDFT;
class ProcessImage {
	private:
		MyDFT* refMydft;
	public:
	static void printText(char * text, 
		MyDFT &refMydft, 
		bool randomPosition = true,
		bool randomColor = true
		);
};

V implementaci MyDFT::getSpectrum mám

ProcessImage::printText("Oo", this);


A tak bych ještě potřeboval poradit jak objekt předat referencí aby to neházelo tuto chybu

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
9. 6. 2016   #12
-
0
-

#11 oxidián
referenci predas tim ze dereferencujes this:

*this

Nebo s tim pracujes rovnou jako s pointerem...

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
9. 6. 2016   #13
-
0
-

Dík, no konečně jsem to zjimpiloval :-)

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
9. 6. 2016   #14
-
0
-

Jak změnit návratový typ u této funkce:

cv::Mat * MyDFT::getImage(int file_no){
 return &this->images[file_no];


this->images[file_no] obsahuje cv::Mat - zřejmě pointer na obraz.
 

cv::Mat * I = refMydft.getImage(file_no);    
  1. xmax = (*I).cols;

    Nevypadá hezky a chtěl bych to zpřístupnit takto I.cols nebo I->cols ale lépe I.cols


Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
9. 6. 2016   #15
-
0
-

#14 oxidián
klasicky  I->cols musi jit

pokud chces teckovou notaci, tak:

  cv::Mat & I = *(refMydft.getImage(file_no))

jen to chce opravdu hlidat, ze tam nemas NULL pointer!

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
9. 6. 2016   #16
-
0
-

Takže takto

int xmax;
cv::Mat * I = refMydft.getImage(file_no);	
xmax = refMydft.images[file_no].cols;
xmax = (*I).cols;
xmax = I->cols;
cv::Mat & jinak = *(refMydft.getImage(file_no));
xmax = jinak.cols;

Paráda

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
9. 6. 2016   #17
-
0
-

Jak vyřešit toto - funkce původně vracela int (-1,-2 byly chyby ), teď když nastane chyba vracím nullptr ale protože návratový typ má být * na instanci cv::Mat tak to krachne. Mě by zajímalo jak se ošetřují chyby v takových případech. Co vrátit, když obraz se nepovedlo načíst? Prostě vrátit prázdný objekt bez dat? To ale nepředám informaci do vnějšího kontextu že došlo k chybě.

cv::Mat * MyDFT::getSpectrum(const char * file, int flag){
		file_no++;
		if (flag == cv::IMREAD_GRAYSCALE)
		{
		if (file) // except nullptr
			{
			this->images[file_no] = cv::imread(file, flag);
			if( this->images[file_no].empty())
				{ std::cout << "File not found." << std::endl;
				return nullptr;
				}
			}
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
9. 6. 2016   #18
-
0
-

#17 oxidián
Co třeba vyhodit výjimku?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
q
~ Anonymní uživatel
219 příspěvků
10. 6. 2016   #19
-
0
-

#17 oxidián
Vracíš ukazatel, ale protože to má být ukazatel, tak to... Počkat... Proto to asi nekrachne ;-)

Předtím jsi návratovou hodnotu netestoval? Tak to udělej i teď, jak už ti KIIV psal.

Nahlásit jako SPAM
IP: 78.156.159.–
oxidián0
Grafoman
10. 6. 2016   #20
-
0
-

#18 Kit
Neumím pracovat s vyjímkama. Sice jsem to už několikrát viděl ale nikdy jsem nepochopil co to vlastně dělá a jak to funguje. Jsem zvyklý spíš na if (něco) then něco

Jsem schopen tu OpenCV knihovnu odladit a krachne hned po načítání obrazu imread()... release -> crash

Mat& Mat::operator = (Mat&& m)
{
    release();
inline void Mat::release()
{
    if( u && CV_XADD(&u->refcount, -1) == 1 )
        deallocate();
    u = NULL;
    datastart = dataend = datalimit = data = 0;
    for(int i = 0; i < dims; i++)
        size.p[i] = 0;
}

Na prvním řádku to krachne, u->refcount není nastaven je tam hodnota -int
 

Unhandled exception at 0x00411c78 in ...exe ... 0xC00000 5
Access violation writing at location

Nahlásit jako SPAM
IP: 78.45.87.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 94 hostů

Podobná vlákna

Typ pisma — založil Ondro

Typ osobnosti — založil tobel

Navratovy typ — založil Gadael

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý