Tam Sürümünü Görmek İçin : C++ ilgili
header dosyasında:
----------------------
class List{
private:
struct ListNode{
ListItemType item;
ListNode *next;
};
ListNode *find(int index)const;
};
----------------------
şekilnde geçen fonksiyonu, implement dosyasında
List::*find(int index) const{}
diye define edince hata veriyor.
List::ListNode *List::find(int index) const{}
diye yazmam gerekiyormuş.
Bu satır ne anlama geliyor açıklarmısınız lütfen iki kere "::" demiş.
teşekkür ederim.
acehreli
29/08/2006, 08:13
Islevler soyle tanimlanirlar ya:
DonusTuru islev_adi(/* parametreler */)
{
/* islemler */
}
Buna bakinca, senin son yazdigin islevin parcalari da soyle aciklanabilir:
DonusTuru --> List::ListNode *
islev_adi --> List::find
parametreler --> int index
Iki tane ':' karakteri yan yana geldiginde bir ismin hangi ad alani icinde oldugunu belirtir. List::find yazinca nasil List'in icindeki find'dan bahsettigimizi soyluyorsak, List::ListNode yazinca da ayni sekilde List'in icindeki ListNode'u belirtmis oluruz.
O satirda bir de 'const' var... Onun anlami da, List::find islevinin, o an uzerinde cagrildigi List nesnesinde degisiklik yapmayacak oldugudur. Ornegin soyle bir kod olsa:
List benim_listem;
/* ... */
List::ListNode * bulunan = benim_listem.find(42);
O find satirindan sonra benim_listem adli nesnenin degismedigini bekleyebiliriz demektir. O ozelligi sayesinde de 'find' islevini sabit List nesneleri uzerinde de cagirabiliriz:
const List sabit_listem = bir_yerden_al();
/* ... */
const List::ListNode * bulunan = sabit_listem.find(42);
O kod derlenebilir; cunku 'find' sabit_listem'de degisiklik yapmaz.
Ayrica not: Son verdigim iki ornegin calisabilmesi icin List::ListNode'un 'private' olmamasi gerekir. Yoksa senin orneginde oldugu gibi 'private' olarak tanimlanirsa, kimse 'find' islevinin donus turunu kullanamaz. Yani kimse benim umdugum gibi 'bulunan' gibi bir gosterge tanimlayamaz.
Tabii ayni sey 'find' icin de gecerli. Hem ListNode'un hem de 'find'in 'public' olmalari gerekiyor...
Ali
@acehreli
teşekkür ederim biraz bişeyler anladım lakin,
header yazdığım gibiyken ve
fonksiyon
List::ListNode *List::find(int index) const{}
şeklindeyken hata vermiyor.
fonksiyon
List::ListNode * find(int index) const{}
şeklindeyken "modifiers not allowed on nonmember functions" hatası veriyor. Bu ne demek?
fonksiyon
List::ListNode * find(int index){}
şeklindeyken "cannot access private struct declared in class 'List' " hatası veriyor. Bu ne demek?
complier: visual c++ 2005
çıkamadım işin içinden lütfen yardım edin,
teşekkürler.
acehreli
29/08/2006, 20:32
Hangisinin calistigini biliyorsun ve calisiyor.... Neden degistiriyorsun? :) Hata mesajlarini anlamak icin denedigini dusunerek acikliyorum:
1)
List::ListNode * find(int index) const{}
find'in basindaki List::'i kaldirip yazdigin zaman, List'in 'find' islevini degil de serbest bir 'find' islevini tanimlamis oluyorsun. Parametre listesinden sonra belirtilen 'const' ise yalnizca uye islevler icin gecerli oldugu icin de onun icin "not allowed on nonmember functions (uye olmayan islevlerde kullanilamaz)" hatasini aliyorsun. ['const' ve 'volatile' tanimlayicilarina 'modifier' denir.]
2)
List::ListNode * find(int index){}
Bu durumda bir onceki hatanin nedeni olan 'const'i kaldirmissin; o hata gitmis. Simdi ise ilk mektubumda yazdigimdaki durumla karsi karsiyasin. Bu islevi cagirdigin noktada List::ListNode adli yapiyi kullanmaya calisiyorsun ama o yapi 'private'; yani List'e "ozel" bir yapi... O tUrU List'in ve arkadaslarinin disinda kimse kullanamaz.
Soyledigim gibi, zaten o iki denemen de yanlis, cunku sen serbest bir 'find' islevi degil, List'in find islevini tanimlamak istiyorsun; onun icin List::find olmasi gerekiyor. Bence su ornekten yola cikabilirsin:
// Bu bir yerde bir sekilde tanimli olmali; uyduruyorum...
struct ListItemType
{
double agirlik;
};
class List
{
public:
struct ListNode
{
ListItemType item;
ListNode *next;
};
ListNode * find (int index) const;
};
// List::find'in gerceklenmesi:
List::ListNode * List::find (int index) const
{
/* Burada index'e karsilik gelen ListNode'u bulup dondurecegiz. Eger
* bulunamazsa, geleneksel olarak NULL (veya 0) dOndUrulur. Ben oyle
* yapiyorum. */
return 0;
}
#include <iostream>
int main()
{
// Bir List nesnemiz var
List benim_listem;
// [...] Burada herhalde icine bir seyler doldururuz
// 42'ye karsilik gelen ListNode'u bulmaya calisalim
List::ListNode * bulunan = benim_listem.find(42);
/*
* Eger bulunursa 0'dan farkli bir gosterge dOndUrdugunu
* biliyorum. Bakalim sifir mi?
*
* Not: "if (bulunan)" yerine "if (bulunan != 0)" da yazabilirdik;
* ayni sey...
*/
if (bulunan) {
// bulunan'in degeri 0'dan farkliymis; demek ki 42'ye karsilik
// gelen bir ListNode varmis; o zaman onu kullanabiliriz.
std::cout << "Buldum: " << bulunan->item.agirlik << '\n';
}
else {
std::cout << "Bulamadim\n";
}
return 0;
}
Ali
Yardımlarınız için çok teşekkürler ama ben hala anlamıyorum, herhalde biraz daha C++ çalışmam gerekiyor. :)
Burada bir "Linked List" yazmaya çalışıyordum.
List.h dosyası:
#include "stdafx.h"
#include "ListException.h"
#include "ListIndexOutOfRangeException.h"
typedef int ListItemType;
class List{
public:
List();
List(const List& aList); //copy constructor
~List();
bool isEmpty() const;
int getLength()const;
void insert(int index, ListItemType newItem)throw(ListIndexOutOfRangeException,ListExc eption);
void remove(int index)throw(ListIndexOutOfRangeException);
void retrieve(int index, ListItemType& dataItem)const throw(ListIndexOutOfRangeException);
private:
struct ListNode{
ListItemType item;
ListNode *next;
};
int size;
ListNode *head;
ListNode *find(int index)const;
void yazdir(); //bunun proje ile ilgisi yok kıyaslamak için ekledim
};
List.cpp dosyası:
#include "stdafx.h"
#include "List.h" //header
#include <cstddef> //for NULL
#include <cassert> //for assert()
#include <iostream>
using namespace std;
List::List():size(0),head(NULL){} //default constructor
//copy constructor
List::List(const List& aList):size(aList.size){
if(aList.head==NULL)
head=NULL;
else {
//copy first node
head=new ListNode;
assert(head!=NULL);
head->item=aList.head->item;
//copy Rest of the list
ListNode *newPtr=head;
//newPtr points to last node in original list
//origPtr points to nodes in the original list
for(ListNode *origPtr=aList.head->next;
origPtr!=NULL;
origPtr=origPtr->next){
newPtr->next=new ListNode;
assert(newPtr->next!=NULL);
newPtr=newPtr->next;
newPtr->item=origPtr->item;
}
newPtr->next=NULL;
}
}
List::~List(){
while(!isEmpty())
remove(1);
}
bool List::isEmpty() const{
return size==0;
}
int List::getLength() const{
return size;
}
void List::retrieve(int index, ListItemType &dataItem) const{
if ( (index<1)||(index>getLength()) )
throw ListIndexOutOfRangeException("ListIndexOutOfRangeException: insert index out of range");
else{
ListNode *cur=find(index);
dataItem=cur->item;
}
}
void List::remove(int index)throw(ListIndexOutOfRangeException){ /* ... */}
void List::insert(int index, ListItemType newItem){/*...*/}
//yazdir fonksiyonu da private ama onu tek "::" ile yazabiliyorum,
void List::yazdir(){
cout<<"hede";
}
//ama find fonksiyonu için 2 kere "::" "::" gerekiyor, neden?pointer döndüğü için mi?
List::ListNode *List::find(int index) const{
if ( (index<1)||(index>getLength()) )
return NULL;
else{
ListNode *cur=head;
for(int skip=1; skip<index; ++skip)
cur=cur->next;
return cur;
}
}
acehreli
29/08/2006, 22:26
Ilk mektubumdaki "Iki tane ':' karakteri yan yana geldiginde" diye baslayan yeri tekrar oku lutfen. Iki kere kullanilan :: isleci iki degisik yerde kullaniliyorlar: birisi islevin adinda, birisi de dOnUs tUrUnun adinda...
[Not: List::yazdir yazdiginda derleyiciye "List'in icindeki 'yazdir'dan bahsediyorum" diyor oldugunu biliyor musun?]
List::find islevi hangi tUrU dOndUruyor? ListNode isaretcisi mi? Oyle dersen eksik oluyor. Derleyici ListNode diye bir sey bilmiyor; bir anahtar sozcuk degil, o ana kadar bildirilmis bir sey de degil. [Sen insan olarak ListNode'un bir kac satir once tanimlanan List'in icinde bir yapi oldugunu gorebiliyorsun ama derleyici insan degil :)]. ListNode'un nerede oldugunu da soylemen gerekiyor. Onun icin List::ListNode yaziyorsun.
Ali
List::find islevi hangi tUrU dOndUruyor? ListNode isaretcisi mi? Oyle dersen eksik oluyor. Derleyici ListNode diye bir sey bilmiyor; bir anahtar sozcuk degil, o ana kadar bildirilmis bir sey de degil. [Sen insan olarak ListNode'un bir kac satir once tanimlanan List'in icinde bir yapi oldugunu gorebiliyorsun ama derleyici insan degil :)]. ListNode'un nerede oldugunu da soylemen gerekiyor. Onun icin List::ListNode yaziyorsun.
Ali
şimdi anladım, sabırla cevap verdiğiniz için çok teşekkürler :super:
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.