0

I've stuck with compilation error related with operator=.

error C2248: 'std::basic_ifstream<_Elem,_Traits>::operator =' : cannot access private member declared in class 
'std::basic_ifstream<_Elem,_Traits>

Here's the code:

class A1 {

protected:
    regex someValue;

public:
    A1(){};
    A1(const string & value_A ): someValue(value_A){};
};

class B2 : public A1 {

public:
    B2(const char * value_B): A1(value_B){filewithResults.open("Output1.txt");};
    ofstream filewithResults; // seems this parameter cause complatiion problems
};

int main(){

    B2 object1 = B2("something1"); 
    B2 object2 = B2("something2"); 

    //then in program I assign object1 = object2;
}

result:

So seems public "ofstream filewithResults" cause problem. How to fit it ?

There is also releated to it error:

C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\fstream(1035) : see declaration of 'std::basic_ofstream<_Elem,_Traits>::operator ='
    1>          with
    1>          [
    1>              _Elem=char,
    1>              _Traits=std::char_traits<char>
    1>          ]
    1>          This diagnostic occurred in the compiler generated function 'B2 &B2::operator =(const B2 &)'
gen_next
  • 97
  • 1
  • 12
  • Related: [copy-and-swap](http://stackoverflow.com/q/3279543/509868) – anatolyg Mar 29 '15 at 11:22
  • One option for "defining" the assignment operator is right there in your code: don't do anything, and just add `object1 = object2` wherever you need. Does it create any specific problems for you? If yes, which problems? If no, do you want to identify potential problems of this approach? – anatolyg Mar 29 '15 at 11:28
  • If `regex` is an `std::regex`, this is a bad example: you don't need to implement your own copy constructor or assignment operator. Just let the compiler do its thing. – juanchopanza Mar 29 '15 at 11:31
  • compilation failed due to: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\fstream(1035) : see declaration of 'std::basic_ofstream<_Elem,_Traits>::operator =' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits 1> ] 1> This diagnostic occurred in the compiler generated function 'B1 &B1::operator =(const usersChoice &)' ..... thats why I created question – gen_next Mar 29 '15 at 11:40
  • Then something else is wrong. The code you posted [compiles OK](http://ideone.com/TER8Pz). – juanchopanza Mar 29 '15 at 11:53
  • error C2600: 'B2::operator =' : cannot define a compiler-generated special member function (must be declared in the class first) – gen_next Mar 29 '15 at 12:06
  • That probably means you have a definition for that operator somewhere, without declaring it in the class. – juanchopanza Mar 29 '15 at 12:14
  • @gen_next I edited your question to the best of my understanding. You are invited to improve it. One unclear point is why the compiler spews something related to `std::basic_ofstream`. Probably your `class A1` or `class B2` has a `std::basic_ofstream` (or some other stream) member. If so, please update your code so the question can be answered. If not, please provide any other info that you think is significant. – anatolyg Mar 29 '15 at 15:08
  • @anatolyg - I clarified question – gen_next Mar 29 '15 at 16:27

2 Answers2

1

You have a member in your class B2 that cannot be copied. This points at a conceptual problem that you have to think about, before you decide how to get rid of the compilation error.

Any object of class B2 is designed to write results to a file with a hard-coded name. What should be the behavior if there are two objects writing to that file?

If they should both write to the same file, and ensure no data is lost:

  • You can hold a pointer (ofstream* or, better, std::shared_ptr<ofstream>) instead of a stream. You might want to add mutexes around its usage, if your application is multi-threaded. However, this still doesn't handle the case when your object1 and object2 are created independently and open the same file for writing - object2 will fail.
  • You can hold a file name (std::string) - and open/close the stream when appropriate.

If you don't care what the objects write to your stream:

  • Add an assignment operator, whose implementation copies everything except the stream. The stream will not be copied; in one of the objects, the stream will fail to open the output file, and all writes to it will be ignored.

    class B2 : public A1 {
        B2& operator=(B2 other_object);
    };
    
    B2& B2::operator=(B2 other_object)
    {
        A1::operator=(other_object);
        // if B2 had any other members, you'd assign them here:
        some_member = other_object.some_member;
    }
    

    Note that you have to include both the declaration and the definition:

    B2& operator=(B2 other_object); // declaration
    B2& B2::operator=(B2 other_object) {...} // definition
    

    (the two can be combined if the definition is inline: class B2 { ... here ... })

If you'd rather write to different files:

  • Pass the filename to each object of class B2. In a constructor or a dedicated method:

    B2(const char * value_B, std::string resultFilename):
        A1(value_B),
        filewithResults(resultFilename)
    {
    }
    
  • Generate a unique filename in the constructor instead of using Output1.txt

anatolyg
  • 26,506
  • 9
  • 60
  • 134
-2

If You don't want to get two references for the same object, then You should copy the object, ie. construct the new instance from the old one's contents. Why not define the copy constructor and let it do the business?

riodoro1
  • 1,246
  • 7
  • 14