Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: вопрос о дружественных конструкциях
Форум программистов > Системное программирование > C, С++ и С Builder > Общие вопросы по С и С++
Docker
возможно кому-то покажется что я задаю тупой вопрос... но помогите разобраться с проблемой нормально, а не так, как это сделал я smile.gif
Суть вопроса такова, ниже приведен код:

// strngbad.h -- flawed string class definition
#include <iostream>
using namespace std;
#ifndef STRNGBAD_H_
#define STRNGBAD_H_
class StringBad
{
private:
   char * str;             // pointer to string
   int len;                // length of string
   static int num_strings; // number of objects
public:
   StringBad(const char * s); // constructor
   StringBad();               // default constructor
   ~StringBad();              // destructor
// friend function
   friend ostream & operator<<(ostream & os, const StringBad & st);
};
#endif


// strngbad.cpp -- StringBad class methods
#include <iostream>
#include <cstring>                 // string.h for some
#include "strngbad.h"
using namespace std;

// initializing static class member
int StringBad::num_strings = 0;

// class methods
StringBad::StringBad(const char * s)     // construct StringBad from C string
{
   len = strlen(s);               // set size
   str = new char[len + 1];       // allot storage
   strcpy(str, s);                // initialize pointer
   num_strings++;                 // set object count
   cout << num_strings << ": \"" << str
        << "\" object created\n"; // For Your Information
}

StringBad::StringBad()                   // default constructor
{
   len = 4;
   str = new char[4];
   strcpy(str, "C++");            // default string
   num_strings++;
   cout << num_strings << ": \"" << str
        << "\" default object created\n";  // FYI
}

StringBad::~StringBad()                     // necessary destructor
{
   cout << "\"" << str << "\" object deleted, ";    // FYI
   --num_strings;                    // required
   cout << num_strings << " left\n"; // FYI
   delete [] str;                    // required
}

ostream & operator<<(ostream & os, const StringBad & st)
{
   os << st.str;
   return os;
}


// vegnews.cpp -- using new and delete with classes
// compile with strngbad.cpp
#include <iostream>
using namespace std;
#include "strngbad.h"

void callme1(StringBad &);  // pass by reference
void callme2(StringBad);    // pass by value

int main()
{
   StringBad headline1("Celery Stalks at Midnight");
   StringBad headline2("Lettuce Prey");
   StringBad sports("Spinach Leaves Bowl for Dollars");
   cout << "headline1: " << headline1 << endl;
   cout << "headline2: " << headline2 << endl;
   cout << "sports: " << sports << endl;
   callme1(headline1);
   cout << "headline1: " << headline1 << endl;
   callme2(headline2);
   cout << "headline2: " << headline2 << endl;
   cout << "Initialize one object to another:\n";
   StringBad sailor = sports;
   cout << "sailor: " << sailor << endl;
   cout << "Assign one object to another:\n";
   StringBad knot;
   knot = headline1;
   cout << "knot: " << knot << endl;  
   cout << "End of main()\n";
   
   return 0;
}

void callme1(StringBad & rsb)
{
    cout << "String passed by reference:\n";
    cout << "    \"" << rsb << "\"\n";
}

void callme2(StringBad sb)
{
    cout << "String passed by value:\n";
    cout << "    \"" << sb << "\"\n";
}


ВОПРОС: почему при компиляции данного кода (Microsoft Visual Studio 6.0) возникает ошибка error C2248: 'str' : cannot access private member declared in class 'StringBad' ?
Ведь дружественные конструкции могут обращаться к скрытым членам класса.

p.S. сам то я режил проблему заменой строк
#include <iostream>
using namespace std;
на строку
#include <iostream.h>
По-моему это смешное решение вопроса, и мне не дает покоя тот факт, что я не понимаю в чем моя ошибка в вышеуказанном коде. Спасибо за внимание и надеюсь ответы.
proc
Ты хоть напиши, в какой строке ошибка
Dokcer
ostream & operator<<(ostream & os, const StringBad & st)
{
os << st.str;
return os;
}

ошибка возникает при попытке обратиться к члену класса, объявленого в
private:
char * str;
grigsoft
могу ошибаться, но френды могут обращаться только к protected - но никак не к private. Все-таки это нарушает смысл приватных переменных.
Guest
to grigsoft

Функция, дружественная по отношению к какому-либо классу, не являясь её элементом, имеет те же права доступа, что и функция элемент. Ведь только определение класса может отличить дружественные функции от прочих, следовательно, за объявлением класса сохраняется право определять, каким функциям можно разрешить доступ к собственным данным.
Docker
Guest - это был я
grigsoft
да , действительно
????
Для: Docker
gcc подхватил и скомпилил без ругани ????
1: "Celery Stalks at Midnight" object created
2: "Lettuce Prey" object created
3: "Spinach Leaves Bowl for Dollars" object created
headline1: Celery Stalks at Midnight
headline2: Lettuce Prey
sports: Spinach Leaves Bowl for Dollars
String passed by reference:
   "Celery Stalks at Midnight"
headline1: Celery Stalks at Midnight
String passed by value:
   "Lettuce Prey"
"Lettuce Prey" object deleted, 2 left
headline2:
Initialize one object to another:
sailor: Spinach Leaves Bowl for Dollars
Assign one object to another:
3: "C++" default object created
knot: Celery Stalks at Midnight
End of main()
"Celery Stalks at Midnight" object deleted, 2 left
"Spinach Leaves Bowl for Dollars" object deleted, 1 left
"╪>=" object deleted, 0 left
"" object deleted, -1 left
"" object deleted, -2 left

Press ENTER to continue.
Guest
to ????
Да, все именно так и должно выглядеть.
Мдя, может это какая "хорошая" особенность моего компилятора?
Стоит Microsoft Visual Studio 6.0 - может кто сталкивался с подобной проблемой именно в нем?

p.S. и все-таки: какая разница в этих двух записях?

1. #include <iostream>
using namespace std;
2. #include <iostream.h>
Docker
кароче выше был снова я, все забываю имя вводить..
????
Цитата(Guest @ 20:04:2006, 10:47 )
Microsoft Visual Studio 6.0
*

у него много глюков с линкером sad.gif поставь sp5 (или sp6 - непомню какой последний) взять можно например тут: ]]>http://updates.ya1.ru/index.php?menu_item=develop]]>

Цитата(Guest @ 20:04:2006, 10:47 )
разница в этих двух записях?

1. #include <iostream>
using namespace std;
2. #include <iostream.h>
*


коротко:

Цитата
First, the .h notation of standard header files was deprecated more than 5 years ago. Using deprecated features in new code is never a good idea. In terms of functionality, <iostream> contains a set of templatized I/O classes which support both narrow and wide characters. By contrast, <iostream.h> classes are confined to char exclusively.
Third, the C++ standard specification of iostream's interface was changed in many subtle aspects. Consequently, the interfaces and implementation of <iostream> differ from <iostream.h>.
Finally, <iostream> components are declared in namespace std whereas <iostream.h> components are declared in the global scope. Because of these substantial differences, you cannot mix the two libraries in one program. As a rule, use <iostream> in new code and stick to <iostream.h> in legacy code that is incompatible with the new <iostream> library.


ещё тут ]]>http://c.ittoolbox.com/documents/popular-q...-iostreamh-1726]]>
Docker
to ????
Спасибо, многое теперь прояснилось. Из-за этих различий <iostream> и <iostream.h> столько мути получилось...
????
Сейчас дома проверил - компилится в MSVS6 SP6, но при выполнении вылетает smile.gif
Разбираться нет времени.

З.Ы. SP6 качал с updates.ya1.ru, файл ~ 60Мб
Docker
to ????
значит буду качать sp6, а то, что при выполнении ошибки - это значит то, что компилятор создал код, работа которого прервалась до завершения работы программы - но это не особенность компилятора - дело в самом коде(там есть некоторые недочеты).

p.S. - спасибо за помощь, а нельзя найти SP6, но чтобы обновлял только Visual C++ ?
????
Цитата(Docker @ 20:04:2006, 21:14 )
а нельзя найти SP6, но чтобы обновлял только Visual C++
*

ищи ]]>http://msdn.microsoft.com/vstudio/download...p6/default.aspx]]>
Docker
Это типо прикола, чтоли? как я по названиям разберусь, где тут именно под С++ ?)

Цитата
The links in this section correspond to separate files available in this download. Download the files most appropriate for you.

File Name:              File Size
VS6sp61.exe            993 KB
VS6sp62.exe            27.4 MB
VS6sp63.exe            9.6 MB
VS6sp64.exe            9.6 MB
VS6sp65.exe            4.6 MB
Vs6sp6S1.exe          2.8 MB
Vs6sp6S2.exe          3.3 MB
Vs6sp6S3.exe          3.1 MB


p.s. нашол в разделе Full Version - Multiple Part Download
p.s.s. видно придется полную версию качать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2008 IPS, Inc.