2012-04-02 42 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

相关问题