вопрос о дружественных конструкциях

  • Автор темы Docker
  • Дата начала
Статус
Закрыто для дальнейших ответов.
D

Docker

#1
возможно кому-то покажется что я задаю тупой вопрос... но помогите разобраться с проблемой нормально, а не так, как это сделал я :)
Суть вопроса такова, ниже приведен код:

// 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>
По-моему это смешное решение вопроса, и мне не дает покоя тот факт, что я не понимаю в чем моя ошибка в вышеуказанном коде. Спасибо за внимание и надеюсь ответы.
 
D

Dokcer

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

ошибка возникает при попытке обратиться к члену класса, объявленого в
private:
char * str;
 

grigsoft

Well-known member
15.11.2005
735
0
#4
могу ошибаться, но френды могут обращаться только к protected - но никак не к private. Все-таки это нарушает смысл приватных переменных.
 
G

Guest

#5
to grigsoft

Функция, дружественная по отношению к какому-либо классу, не являясь её элементом, имеет те же права доступа, что и функция элемент. Ведь только определение класса может отличить дружественные функции от прочих, следовательно, за объявлением класса сохраняется право определять, каким функциям можно разрешить доступ к собственным данным.
 
?

????

#8
Для: 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.
 
G

Guest

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

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

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

Docker

#10
кароче выше был снова я, все забываю имя вводить..
 
?
#11
<!--QuoteBegin-Guest+20:04:2006, 10:47 -->
<span class="vbquote">(Guest @ 20:04:2006, 10:47 )</span><!--QuoteEBegin-->Microsoft Visual Studio 6.0
[snapback]34073" rel="nofollow" target="_blank[/snapback]​
[/quote]
у него много глюков с линкером :( поставь sp5 (или sp6 - непомню какой последний) взять можно например тут: [snapback]34073" rel="nofollow" target="_blank[/snapback]</div>[/quote]

коротко:

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
 
D

Docker

#12
to ????
Спасибо, многое теперь прояснилось. Из-за этих различий <iostream> и <iostream.h> столько мути получилось...
 
?
#13
Сейчас дома проверил - компилится в MSVS6 SP6, но при выполнении вылетает :)
Разбираться нет времени.

З.Ы. SP6 качал с updates.ya1.ru, файл ~ 60Мб
 
D

Docker

#14
to ????
значит буду качать sp6, а то, что при выполнении ошибки - это значит то, что компилятор создал код, работа которого прервалась до завершения работы программы - но это не особенность компилятора - дело в самом коде(там есть некоторые недочеты).

p.S. - спасибо за помощь, а нельзя найти SP6, но чтобы обновлял только Visual C++ ?
 
D

Docker

#16
Это типо прикола, чтоли? как я по названиям разберусь, где тут именно под С++ ?)

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. видно придется полную версию качать.
 
Статус
Закрыто для дальнейших ответов.