Thread: use of private members

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    use of private members

    Here's another clunky experiment that don't work right:
    Code:
    #include <iostream>
    #include <vector>
    using namespace std;
    
    class fibvec  {
    	vector<int> series;
    	unsigned int len;
    	public:
    		fibvec() {
    			series.reserve(2);
    			series[0] = series[1] = 1;
    			len = 2;
    		}
    		int digit (int pos) {
    			int i, j = 0;
    			if (pos >= len) {
    				int nlen = pos+1;
    				series.reserve(nlen);
    				for (i=len;i<nlen;i++)
    					series[i] = series[i-1] + series[i-2];
    				len = nlen;
    			}
    			return series[pos];
    		}
    };
    
    
    int main() {
    	int i;
    	fibvec eg;
    
    	for (i=5;i<10;i++) cout << eg.digit(i) << '\n';
    
    	return 0;
    }
    It doesn't work because within fibvec.digit values for "series" are not kept -- everything is always 0. How can I render this "static" or something? Eg, in perl, a constructor returns a special reference to a hash that contains any number and type of elements (it's special in the sense that the class methods can then be used on it). But I cannot "return" anything with a C++ constructor -- do I have to make fibvec derived from vector (I would assume not, since apparently deriving things from the standard containers is a bad practice).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    I have no idea what the problem is you're describing. But one problem is that you'll need resize rather than reserve. Also, why even have a length, isn't that what the .size() function on a vector is for? Of course, that only works if you use resize rather than reserve.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Yeah, you should be using resize() instead of reserve(), and you do not need len. However, suppose you wanted to create a vector of two ints, both set to 1. There is an easy way using an appropriate constructor:
    Code:
    std::vector<int> series(2, 1); // 2 ints, both set to 1.
    You can get this same effect for a member variable using the constructor initialisation list:
    Code:
    fibvec() : series(2, 1) {}
    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

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by EVOEx View Post
    I have no idea what the problem is you're describing. But one problem is that you'll need resize rather than reserve. Also, why even have a length, isn't that what the .size() function on a vector is for? Of course, that only works if you use resize rather than reserve.
    Whew! Using resize instead of reserve made the difference (why?). "This informs the vector of a planned increase in size," -- does that mean you would call reserve then resize? So what is the purpose of reserve?


    The len got left in there from an earlier version where I was trying to work around the problem caused by reserve, by using an init method...blah blah blah.

    Thanks.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    Yeah, you should be using resize() instead of reserve(), and you do not need len. However, suppose you wanted to create a vector of two ints, both set to 1. There is an easy way using an appropriate constructor:
    Okay, but I cannot do that here:
    Code:
    class fibvec  {
    	vector<int> series(2,1);   
    for whatever reason.

    [edit] alright, I get it: constructor initialisation list
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Or just use push_back() instead of resize()?

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Okay. Reserve reserves the minimum amount of memory, but doesn't allow the vector to use it yet. Resize actually resizes the vector so that you can use that many elements.

    Reserve is useless except for optimization. Let's say you know you'll push_back 1000 times. You could simply call push_back 1000 times and let the vector handle it. However, that might cause the vector to reallocate the memory 1000 times, which is fairly slow. Usually it won't, but it usually will make it reallocate the memory a few times.
    To speed up things you can simply call reserve to make sure the vector allocates the required space for those 1000 elements directly. All the subsequent push_backs won't need reallocations (which are quite costly).

    So, if you know how many elements are going to be added, and this number is relatively great, it often makes it a bit faster to call reserve first.

    Finally, it might be better to make the vector static in the class, as the data is shared over all instances of the class. This would mean that even if you generate thousands of instances of the class, you'll only need one vector. In fact, the class instance might not require any memory at all, then.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by EVOEx
    Reserve is useless except for optimization.
    There is another use: to avoid invalidation of iterators, pointers and references due to a reallocation.
    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

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Hmmm. This seems to work then:
    Code:
    				int *ref;
    				series.reserve(nlen);
    				for (i=series.size();i<nlen;i++) {
    					ref = &series.back();
    					series.push_back(*ref + *(--ref));
    				}
    Altho I would assume it is less optimal than just resizing and using [].
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by MK27 View Post
    Hmmm. This seems to work then:
    Code:
    				int *ref;
    				series.reserve(nlen);
    				for (i=series.size();i<nlen;i++) {
    					ref = &series.back();
    					series.push_back(*ref + *(--ref));
    				}
    Altho I would assume it is less optimal than just resizing and using [].
    I don't think this line is valid, as the behaviour, I think, is undefined:
    Code:
    *ref + *(--ref)
    And good point laserlight.

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by EVOEx View Post
    I don't think this line is valid, as the behaviour, I think, is undefined:
    Yeah, hadn't thought about that. I do get this:
    warning: operation on ‘ref’ may be undefined
    But thot it was about the range...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    I think (and please correct me if I'm wrong, because I'd like to know as well) it is undefined because the c++ standard doesn't specify when the decrement operator happens. Ie
    Say ref points to series[3]..
    Code:
    series.push_back(*ref + *(--ref));
    would this mean
    Code:
    series.push_back(series[3] + series[2]);
    or
    Code:
    series.push_back(series[2] + series[2]);
    ?


    As for the implementation of digit(), personally I would do something like
    Code:
    int digit (int pos)
    {
    	if(pos <= 0) return 0;
    	if (pos > series.size())
    	{
    		if(pos > series.capacity())
    			series.reserve(pos);
    		for (int i=series.size();i<pos;i++)
    			series.push_back(series[i-1] + series[i-2]);
    	}
    	return series[pos-1];
    }

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Well, I ended up with something pretty close to that, here's the whole shebang:
    Code:
    class fibvec  {
    	vector<int> series;
    	public:
    		fibvec() : series(2,1) {}
    		int digit (unsigned int pos) {
    			if (pos >= series.size()) {
    				int start = series.size(), nlen = pos+1;
    				series.resize(nlen);
    				for (;start<nlen;start++) series[start] = series[start-1] + series[start-2];
    			}
    			return series[pos];
    		}
    };
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Good job, small bug though
    Using Fibonacci number - Wikipedia, the free encyclopedia as reference, your class outputs
    Code:
    f(0) = 1
    f(1) = 1
    f(2) = 2
    f(3) = 3
    f(4) = 5
    f(5) = 8
    f(6) = 13
    f(7) = 21
    f(8) = 34
    f(9) = 55
    f(10) = 89
    f(11) = 144
    f(12) = 233
    f(13) = 377
    f(14) = 610
    f(15) = 987
    f(16) = 1597
    f(17) = 2584
    f(18) = 4181
    f(19) = 6765
    f(20) = 10946
    For any (pos) it outputs the fibonacci number for (pos+1)

    Edit: I realized that this might be intentional.. If so just ignore this post

  15. #15
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by _Mike View Post
    For any (pos) it outputs the fibonacci number for (pos+1)
    That's just my ignorance of math -- a set in math starts with an index of 1, not 0, right?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Currency Calculator
    By desiamerican in forum C# Programming
    Replies: 1
    Last Post: 01-21-2010, 09:53 PM
  2. Using private class members in static functions
    By sethjackson in forum C++ Programming
    Replies: 2
    Last Post: 09-23-2005, 09:54 AM
  3. webBrowser problem
    By algi in forum C# Programming
    Replies: 7
    Last Post: 08-19-2005, 09:35 AM
  4. Need help with calculator program
    By Kate in forum C# Programming
    Replies: 1
    Last Post: 01-16-2004, 10:48 AM
  5. Accessing private data members
    By maloy in forum C++ Programming
    Replies: 11
    Last Post: 10-04-2002, 02:48 PM