2012-04-02 41 views
-3

頭文件:爲什麼以下函數可以在不聲明爲朋友或成員函數的情況下訪問類成員?

// pe10-8arr.h -- header file for a simple list class 

#ifndef SIMPLEST_ 
#define SIMPLEST_ 

// program-specific declarations 
const int TSIZE = 45;  // size of array to hold title 
struct film 
{ 
    char title[TSIZE]; 
    int rating; 
}; 

// general type definitions 
typedef struct film Item; 

const int MAXLIST = 10; 
class simplist 
{ 
private: 
    Item items[MAXLIST]; 
    int count; 
public: 
    simplist(void); 
bool isempty(void); 
bool isfull(void); 
    int itemcount(); 
bool additem(Item item); 
    void transverse(void (*pfun)(Item &item)); 
}; 

#endif 

代碼使用報頭:

#include "pe10-8arr.h" 

simplist::simplist(void) 
{ 
    count = 0; 
} 

bool simplist::isempty(void) 
{ 
    return count == 0; 
} 

bool simplist::isfull(void) 
{ 
    return count == MAXLIST; 
} 

int simplist::itemcount() 
{ 
    return count; 
} 
bool simplist::additem(Item item) 
{ 
    if (count == MAXLIST) 
     return false; 
    else 
     items[count++] = item; 
    return true; 
} 

void simplist::transverse(void (*pfun)(Item &item)) 
{ 
    for (int i = 0; i < count; i++) 
     (*pfun)(items[i]); 
} 

#include <iostream> 
#include <cstdlib>   // prototype for exit() 
#include "pe10-8arr.h"  // simple list class declaration 
           // array version 
void showmovies(Item &item); // to be used by transverse() 

int main(void) 
{ 
    using namespace std; 
    simplist movies;  // creates an empty list 
    Item temp; 

    if (movies.isfull()) // invokes isfull() member function 
    { 
     cout << "No more room in list! Bye!\n"; 
     exit(1); 
    } 
    cout << "Enter first movie title:\n"; 
    while (cin.getline(temp.title,TSIZE) && temp.title[0] != '\0') 
    { 
     cout << "Enter your rating <0-10>: "; 
     cin >> temp.rating; 
     while(cin.get() != '\n') 
      continue; 
     if (movies.additem(temp) == false) 
     { 
      cout << "List already is full!\n"; 
      break; 
     } 
     if (movies.isfull()) 
     { 
      cout << "You have filled the list.\n"; 
      break; 
     } 
     cout << "Enter next movie title (empty line to stop):\n"; 
    } 
    if (movies.isempty()) 
     cout << "No data entered. "; 
    else 
    { 
     cout << "Here is the movie list:\n"; 
     movies.transverse(showmovies); 
    } 
    cout << "Bye!\n"; 
    return 0; 
} 

void showmovies(Item &item) 
{ 
     std::cout << "Movie: " << item.title << " Rating: " 
      << item.rating << std::endl; 

} 

以上只是編譯和成功運行的代碼。誰能告訴我爲什麼函數showmovies()可以使用引用訪問simplist的項目成員,而不被聲明爲好友函數或成員函數?

+3

我不太清楚你在問什麼; 'showmovies'使用你直接傳遞給它的'item'參數;它不會觸及'simplist' – 2012-04-02 15:18:39

+0

showmovies不會調用成員函數,它只會從Item結構中獲取字段。 – 2012-04-02 15:20:07

+2

在結構中默認情況下,所有內容都是公共的。 – BoBTFish 2012-04-02 15:20:15

回答

0

該功能是交給Item對象(通過引用),它不知道或關心它來自哪裏。函數的調用者實際上是從完整對象內部拉動對象的函數,但transverse通過成爲類的成員具有訪問權。

+0

,但函數指針無法訪問simplist類的成員 – JDein 2012-04-02 15:29:10

+0

@JDein:它不訪問* simplist *的成員,它訪問傳遞的對象引用。考慮到你把鑰匙留給你的房子給朋友,朋友進來,借了一張DVD給我。我是否需要成爲你的朋友才能觀看DVD?我闖入你的房子?不,你信任和接近的人進入了你的房子,挑選了這個物品並交給了我。我甚至不知道它是否來自你隔壁房屋的房子。 – 2012-04-02 16:07:46

+0

但是那樣的話,任何把鑰匙給我房子的人都可以修改我房子裏的內容,這聽起來不像是一個bug? – JDein 2012-04-03 03:01:18

9

結構成員的默認可見性爲public。該功能只使用Item,而不是simplist

5

showMoviesItem爲參數。它不在乎它是否是會員。

Itemstruct,其字段爲public,除非另有聲明。

0

內simplist:

void simplist::transverse(void (*pfun)(Item &item)) 
{ 
    for (int i = 0; i < count; i++) 
     (*pfun)(items[i]); 
} 

要調用從橫向(一個simplist的成員)showmovies,這樣你就可以訪問所有的類屬性,無論知名度。

+0

聽起來像一個bug,不是嗎。 – JDein 2012-04-02 15:36:30

+0

爲什麼這應該是一個bug? – 2012-04-02 16:57:17

+0

考慮下面的代碼,我可以修改simplist類的數據成員在函數showmovies() void showmovies(Item&item) { \t cout <<「原始內容...」<< endl; 的std ::法院<< 「電影:」 << item.title << 「評級:」 << item.rating <<的std :: ENDL; \t的cout << 「修改後的內容......」 << ENDL; \t的strcpy(item.title, 「修飾的」); \t item.rating = 0; \t 的std ::法院<< 「電影:」 << item.title << 「評級:」 << item.rating <<的std :: ENDL; } – JDein 2012-04-03 03:08:19

相關問題