Thread: Constructor Initialiser List

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    173

    Constructor Initialiser List

    Ok, I'm having a weird problem with getting my code to compile. The compiler (g++) keeps telling me that the "copy constructor" is private and gives me "error: within this context". Here's my following code:

    Code:
    #include <iostream>
    #include <cmath>
    
    class Crypt {
    	private:
    		std::istream strm;
    		int n;
    		int p;
    		int k;	// want to find this value
    	public:
                    // problem is here
    		Crypt(std::istream &is): strm(is), n(0), p(0), k(0) 
    		{ 
    		}
    
    		void getpair();
    		void print() 
    		{
    			std::cout << "n: " << n << " p: " << p << " k: " << k << std::endl;
    		}
    			
    		int calculate();
    };
    
    int main(int argc, char **argv)
    {
    	Crypt cval(std::cin);	/* apply default constructor */
    	cval.getpair();
    	std::cout << cval.calculate() << std::endl;
    	return 0;
    }
    
    inline void Crypt::getpair()
    {
    	/* could use some improvement by checking */
    	int val1;
    	std::cin >> val1;
    	n = val1;
    	std::cin >> val1;
    	p = val1;
    }
    
    inline int Crypt::calculate()
    {
    	int val = 0;
    	/* need to fix casts/variable types */
    	for (k = 0; k < p; k++) {
    		val = static_cast<int> (std::pow(static_cast<double>(k), static_cast<double>(n)));
    		if (val == p) {
    			return k;
    		}
    	}
    	return -1;
    }
    What I'm trying to do in this code segment:
    Code:
    		Crypt(std::istream &is): strm(is), n(0), p(0), k(0) 
    		{ 
    		}
    Is to initialise strm to the value sent in by is. I'm not sure why it's complaining about a copy constructor since I used a reference as the argument for the constructor which shouldn't copy anything. And I also used the constructor initialisation list instead of "copying" it in the body block. I'm literally stuck here with no clue on what's going on. Any help would be great

    EDIT: Here's the full compiler warning:
    Code:
    crypt113.cpp: In copy constructor `std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)':
    /usr/lib/gcc/i486-slackware-linux/3.4.5/../../../../include/c++/3.4.5/bits/ios_base.h:781: error: `std::ios_base::ios_base(const std::ios_base&)' is private
    crypt113.cpp:12: error: within this context
    Last edited by 0rion; 02-19-2006 at 09:20 AM.
    The cost of software maintenance increases with the square of the programmer's creativity.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I used a reference as the argument for the constructor which shouldn't copy anything.
    No, but you do try and make an actual copy of it with
    strm(is)
    This too needs to be a reference (your member variable)

  3. #3
    Registered User
    Join Date
    Apr 2004
    Posts
    173
    Hmm I'm still slightly confused, wouldn't "strm(is)" call the constructor which takes a single std::istream argument (i.e. direct initialisation)? At the moment I can't visualise it properly (still new to C++) - I can't see why strm needs to be a reference and not an actual object. Wouldn't strm act like a "normal" variable getting initialised like:

    Code:
    ...
    std::istream samp(std::cin);
    ...
    Or would that not work? *Argh* got to revise more
    The cost of software maintenance increases with the square of the programmer's creativity.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What if you re-design your class so that you pass the std::istream by reference to whichever member function needs to use it? An example of this would be overloading operator>>
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    samp in your class is a stream varable, streams are, in general, non-copyable. The normal way to design something like this is to have a friend >> operator.
    Code:
    class Crypt {
    ...
    friend std::istream & operator >> (std::istream &, Crypt &);
    };
    std::istream & operator >> (std::istream &is, Crypt &c) {
        return is >> c.n >> c.p;
    }
    int main() {
        Crypt cval;
        if(std::cin >> cval) {
            cval.calculate();
            ...
        }
    }
    You may also want to call calculate() from within the >> operator, so that k is always valid. You may also want to read the values into local varables and only change the target Crypt if all input operations succeed.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Just make strm a reference, like Salem said:
    Code:
    class Crypt {
    	private:
    		std::istream &strm;
    Note that this makes your class non-assignable. If you want it assignable, you must store a pointer. Also note that the Crypt object must not outlive the stream you pass to the constructor.

    Finally, you should make Crypt's constructor explicit, to prevent implicit conversion from an istream to a Crypt, which would make no sense:
    Code:
    public:
    		explicit Crypt(std::istream &is): strm(is), n(0), p(0), k(0)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Link List math
    By t014y in forum C Programming
    Replies: 17
    Last Post: 02-20-2009, 06:55 PM
  2. instantiated from here: errors...
    By advocation in forum C++ Programming
    Replies: 5
    Last Post: 03-27-2005, 09:01 AM
  3. How can I traverse a huffman tree
    By carrja99 in forum C++ Programming
    Replies: 3
    Last Post: 04-28-2003, 05:46 PM
  4. List class
    By SilasP in forum C++ Programming
    Replies: 0
    Last Post: 02-10-2002, 05:20 PM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM