Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Star War Sex Parrot
Oct 2, 2003

I have a class with an array as a private member. What's the proper way to write a getter for that member? If I just return the private member array, am I not then returning a pointer to the private member itself, allowing it to be modified by whatever called the getter?

Adbot
ADBOT LOVES YOU

Star War Sex Parrot
Oct 2, 2003

Dren posted:

Are you in c or c++ and would you be ok with returing a copy to the user?
C++ but I'm not allowed to use std::vector or std::array at this point. I guess I'm using C-style arrays, then?

A copy would be my best bet, I think.

Star War Sex Parrot
Oct 2, 2003

WaterIsPoison posted:

What's the point of learning/using C++ if you can't use any of it's features/best practices? Seriously, if your instructor wants you to learn C, they should just teach you C.
The one programming course that my girlfriend had to take as part of her engineering undergrad was "C++" but had similar restrictions like you mention. She spent more time trying to figure out the quirks of poo poo like C strings than actually learning proper programming practices. She'd have been better off with a single quarter of Python as her sole programming course.

Star War Sex Parrot
Oct 2, 2003

It looks like you need to dynamically allocate an array since the length isn't a compile-time constant. You need to do a heap allocation if the size is to be determined at run-time.

Star War Sex Parrot
Oct 2, 2003

Xerophyte posted:

In C++03:
C++ code:
	char *code = new char[strlen(phrase)];

	// Before returning, throwing exceptions or otherwise leaving your function...
	delete code;
Shouldn't that be delete[]?

Star War Sex Parrot
Oct 2, 2003

He should be using initialization lists instead of assignment inside of the constructors anyway, but then there are a ton of "best practices" issues with that code so I probably shouldn't open a can of worms of nitpicking.

Star War Sex Parrot
Oct 2, 2003

Tusen Takk posted:

do you mean mfgName = mfg and dealerCost = cost?
I'm pretty sure he means: why are you declaring duplicate member variables in your derived classes (mfgName, dealerCost) when they already exist in the base class? If you're going to declare the same members all over again, it defeats one of the biggest reasons for inheritance -- the other being polymorphism.

edit: Also I can tell you right now that this instructor sucks. It looks like he's teaching you bad C++98 with no regard for more recent standards or best practices.

Star War Sex Parrot fucked around with this message at 21:53 on Mar 31, 2014

Star War Sex Parrot
Oct 2, 2003

Tusen Takk posted:

Also lol at my professor for using unsigned integers? I was under the impression that unsigned ints are hilariously bad practice.
There are plenty of examples of bad practice in that code, but unsigned data types absolutely have their place and aren't being used incorrectly in this case.

Star War Sex Parrot fucked around with this message at 02:22 on Apr 8, 2014

Star War Sex Parrot
Oct 2, 2003

Tusen Takk posted:

In EvE Online the turbonerds are always "lol unsigned ints" when you have a stack of object x greater than whatever the largest number an unsigned int can accept or something like that.
Using a signed int wouldn't help you with this.

Star War Sex Parrot
Oct 2, 2003

Every for loop that I write uses an unsigned short int. :smug:

Star War Sex Parrot
Oct 2, 2003

I love C++.

Star War Sex Parrot
Oct 2, 2003

rjmccall posted:

Also I have no idea what language that thing you're doing with -> is even supposed to be from, but it ain't C++.

Subjunctive posted:

Are you sure that -> thing isn't just pseudocode?
Seeing all of this -> discussion mixed with his array hopelessness made me curious if you can actually use it with pointer arithmetic to dereference an array of object's members. I never really use pointer arithmetic with arrays anyway, but -> seems to work.
C++ code:
#include <iostream>

class Butt
{
public:
	int x;
	void Foo() const
	{
		std::cout << x << " butts" << std::endl;
	}
};

int main()
{
	Butt test[5] {6,7,8,9,10};

	(test+2)->Foo();

    return 0;
}
which outputs 8 butts.
Also that probably confused Tusen Takk even more.

Star War Sex Parrot fucked around with this message at 02:51 on Apr 15, 2014

Star War Sex Parrot
Oct 2, 2003

Tusen Takk posted:

Basically this. Coming from Java, it was an especially curvy curveball thrown at me and I'm honestly glad that I'm done with it.
Learn C# :getin:

Star War Sex Parrot
Oct 2, 2003

Tusen Takk posted:

I've heard it's basically the best parts of Java and C++, c/d?
Ehhhh it depends on what you consider the "best parts" of each respective language. If you consider the portability of Java and the performance of C++ to be their best parts, then no C# is not just a perfect language that marries both of those. If you consider Java's garbage collection and Visual Studio for C++ to be their best parts, well then maybe you'd have an argument.

Either way, yes C# is related to both Java and C++ in some ways and I find it to be a very nice language and the .NET Library to be well put together and all have their places in the world. We now return you to C++ chat. :)

Star War Sex Parrot
Oct 2, 2003

Now I'm just left wondering who owns colour and is eventually going to clean it up. Or worse: if it might get deleted before Ball is done with it.

edit: I guess that's what kicked off this whole thing and I should do more than just skim the code in the thread.

qntm posted:

As soon as execution returns from getOneMessage(), colour is taken off the stack, but the returned Ball still retains a pointer to it. Later, when the Ball tries to use the pointer, everything explodes. Obviously, my mistake was to assume that the constructor would take a copy of colour for its own use. Instead I need to make sure that colour remains on the stack (or heap) for at least as long as the returned Ball does.

My question is this: how can I protect myself from this kind of mistake in the future? I didn't realise until later that colour was being passed by reference, which should have been a clue, which I'll put down to inexperience. But beyond this, I'm finding it really hard to reason about C++ code in general. Surely, any method which accepts reference parameters could do something similar. Surely any methods called by that method could do the same. Does this mean I need to laboriously inspect the implementation of every method I ever call, directly or indirectly, just to catch this kind of behaviour? What if the implementation isn't available?

Star War Sex Parrot
Oct 2, 2003

Deus Rex posted:

If you have a Mac Dash gives you handy offline access to cppreference among like a hundred other documentation sets.
I was just thinking about a nicer way to access the cppreference stuff offline, and this is perfect!

Thanks.

Star War Sex Parrot
Oct 2, 2003

Vanadium posted:

I'd expect to see exceptions used in situation where the code that notices the error doesn't know how to handle it, but some code way up in the callstack does, and exceptions are the best way to communicate the error upwards because throw immediately starts unwinding and jumps up the stack to the handler. In your example, you already know what you're gonna do about the error, so you might as well do it right away, and your throw surprisingly doesn't unwind anything or jump anywhere since the handler is basically in the next line anyway.
Basically this. What Hammerite did reminds me of how exceptions are taught in intro C++ classes, but don't actually demonstrate how and when they're actually used. It usually doesn't make a lot of sense to throw exceptions around in the same function, but instead they're used to communicate and even recover from a failure when unwinding the call stack.

Hammerite, what you did could easily just be handled without throwing an exception in the first place and instead just using normal control statements.

Star War Sex Parrot
Oct 2, 2003

You also have to be careful with exceptions in C++ because if you're not adhering to RAII and throw an exception and don't remember to clean stuff up with the handler, you will leak memory.

Star War Sex Parrot
Oct 2, 2003

I'm fairly certain that if whatever is in the try block generates an exception, execution will enter the catch, do some stuff, and then pass the same exception. In theory I think it's a way to do something when an exception is thrown while leaving the actual handling to another point in the program.

Star War Sex Parrot
Oct 2, 2003

Destructors for base classes should generally be made virtual so as to play nice with polymorphism. I assume that's what it's yelling at you about.

Also getters should probably be const functions so the compiler yells at you if you do something dumb like try to modify ivars in a getter.

edit: for the virtual destructor, if you don't actually want to write the implementation, just use "= default";
C++ code:
virtual ~BaseClass() = default;

Star War Sex Parrot
Oct 2, 2003

Xeom posted:

At first it seemed like a way to have functions generate arrays, but everything inside the function goes away once its done being called. I am having a hard time thinking of how to use this guy.
I'm not following your pseudo-code, but anyway: Statically allocated memory will fall out of scope when the function terminates, so you'll have a dangling pointer. You need to use dynamic allocation (new) if you want to pass around pointers between functions. And don't forget to delete (or delete[]) when done with it or you'll leak memory. All of this is a fundamental concept of C++ memory management for all types, not just arrays.

edit: let us know specifically what parts are confusing to you and we'll whip up some code samples. Also I hesitate to use auto when first learning C++ as you really need to be aware of the types of your variables. Here's a good code sample that demonstrates dynamic allocation of arrays.

Star War Sex Parrot fucked around with this message at 23:39 on Jul 8, 2014

Star War Sex Parrot
Oct 2, 2003

Subjunctive posted:

The link in the OP 404s, and I'm in the market for a book to help me absorb C++11/14 improvements and changes in preferred style (like, no new use?!). Kindle strongly preferred, I'm not likely to lug around a paper copy.

I guess there's the upcoming Meyers book, but I bet I have some catching up to do before I'm ready to absorb that. I haven't programmed in anger with auto or rvalue references or similar yet.
Based on the table of contents I saw, you more or less described exactly what Meyers' new book is, so I'd go for that. Speaking of, the draft is now available.

Star War Sex Parrot fucked around with this message at 21:53 on Jul 14, 2014

Star War Sex Parrot
Oct 2, 2003

Edit: never mind that's an initializer list you're using, so my comment is incorrect.

Star War Sex Parrot fucked around with this message at 01:07 on Jul 23, 2014

Star War Sex Parrot
Oct 2, 2003

Standard practice these days seems to be to just use auto when dealing with a type for iterators.

Star War Sex Parrot
Oct 2, 2003

ExcessBLarg! posted:

That's weird, C isn't really the right language to teach to non-majors. There was a brief period where Pascal fell out of favor in education and folks were still suspicious of Java to teach the introductory level, but there's so many more legitimately-useful options if you're going to teach someone one language that they may actually use later.

How common is this still?
At UCLA your 1 required programming class if you're a STEM major (non-CS, EE, etc. obviously) is still C++ (but mostly C) last I checked. My girlfriend is Environmental Engineering and had to take it for her major, though this was a few years ago now so hopefully it's changed. I was baffled at the poo poo they had her learning for someone who's never going to do that type of programming again, especially since they emphasized C over C++ (C strings, little to no OOP, no STL, etc.). I know UCI recently changed its first year CS curriculum to emphasize Python and Java over C or C++, and their C++ class now targets student who already know the basics and spends more time teaching C++11/14 and STL stuff.

Star War Sex Parrot fucked around with this message at 23:46 on Aug 19, 2014

Star War Sex Parrot
Oct 2, 2003

Boz0r posted:

I'm generating random input for a convex hull algorithm in 3D, and when the input list gets large enough, I get a bad_alloc error when n > n^24 even though I haven't run out of RAM or anything.

Here's my code:

code:
void DataBoxDistribution3D(unsigned int testDataSize, std::vector<Vector3D> &dataPoints) {
	std::default_random_engine generator;
	std::uniform_real_distribution<double> uniformDistribution(-1, 1);
	for (size_t i = 0; i < testDataSize; i++) {
		double x = uniformDistribution(generator);
		double y = uniformDistribution(generator);
		double z = uniformDistribution(generator);

		dataPoints.push_back(Vector3D(x, y, z));
	}
}
and I get the error when i=2690677.

What am I doing wrong?
Just as a heads up, you're not seeding your engine with a device which will result in the same "random" results every time you run your program. For example, I made a quick Vector3D class (I assume yours has more to it), copied your distribution generation function, and made a quick and dirty "print them all" function:
C++ code:

#include <iostream>
#include <random>
#include <vector>

class Vector3D
{
	public:

		Vector3D(double x, double y, double z) : x {x}, y {y}, z {z}
		{

		}

		double x;
		double y;
		double z;
};

void DataBoxDistribution3D(size_t testDataSize,
                           std::vector<Vector3D>& dataPoints)
{
	std::default_random_engine generator;
	std::uniform_real_distribution<double> uniformDistribution(-1, 1);

	for (size_t i = 0; i < testDataSize; i++)
	{
		double x = uniformDistribution(generator);
		double y = uniformDistribution(generator);
		double z = uniformDistribution(generator);
		dataPoints.push_back(Vector3D(x, y, z));
	}
}

void printDistribution(const std::vector<Vector3D>& dataPoints)
{
	for (auto i : dataPoints)
	{
		std::cout << i.x << " " << i.y << " " << i.z << std::endl;
	}
}

int main()
{
	std::vector<Vector3D> dataPoints;
	DataBoxDistribution3D(4, dataPoints);
	printDistribution(dataPoints);
	return 0;
}
Then I ran the program 3 times:

matt@sandbox : ~/projects/random $ ./run
-0.829935 0.783223 -0.62062
-0.203983 0.487025 0.12078
0.619133 0.0234251 0.990169
0.933223 -0.147898 0.305997
matt@sandbox : ~/projects/random $ ./run
-0.829935 0.783223 -0.62062
-0.203983 0.487025 0.12078
0.619133 0.0234251 0.990169
0.933223 -0.147898 0.305997
matt@sandbox : ~/projects/random $ ./run
-0.829935 0.783223 -0.62062
-0.203983 0.487025 0.12078
0.619133 0.0234251 0.990169
0.933223 -0.147898 0.305997

See the problem? Now, change your random engine instantiation to:
C++ code:
	std::random_device device;
	std::default_random_engine generator{device()};
And run it a few times:

matt@sandbox : ~/projects/random $ ./run
-0.742602 0.557945 0.370006
0.509726 -0.412112 -0.175772
0.366924 0.630628 0.172798
0.393836 0.653487 -0.638336
matt@sandbox : ~/projects/random $ ./run
0.0349932 0.553798 0.1745
-0.650975 -0.0515622 0.343564
0.65945 -0.0723755 0.398404
0.550028 -0.295123 0.385876
matt@sandbox : ~/projects/random $ ./run
0.520096 -0.423067 0.853396
0.282208 0.62926 0.144895
0.416956 -0.827151 0.300816
0.0987096 0.373157 0.4119

That's much better. If you want to learn more about C++11's random devices, engines, and distributions, I highly recommend reading this short paper.

Star War Sex Parrot fucked around with this message at 05:40 on Oct 1, 2014

Star War Sex Parrot
Oct 2, 2003

That looks like a circular dependency to me.

Star War Sex Parrot
Oct 2, 2003

PRADA SLUT posted:

if (number < 10) { sysCommand += number; } is the problem.
If that's how you want to do it, then you probably need std::to_string(number)

Star War Sex Parrot
Oct 2, 2003

Jewel posted:

I don't think there's any reason to pass a pointer by reference
I suppose it would prevent reassigning the name to refer to something else, but I think you could accomplish the same thing with a well placed const.

Star War Sex Parrot
Oct 2, 2003

VikingofRock posted:

I've run into this before in situations where some member is the result of some expression that depends on another member. Like so:

C++ code:
Class MyClass{
public:
    MyClass(bool foo, int bar) : foo_(foo), bar_(foo_ ? bar : 0) {}
private:
   int bar_;
   int foo_;
};
Yep, as have I. Clang will at least throw a warning if it notices that you're initializing out of order. Valgrind's memcheck probably would too since it tends to get angry if it spots dependencies on uninitialized variables.

Star War Sex Parrot fucked around with this message at 02:50 on Jan 1, 2015

Star War Sex Parrot
Oct 2, 2003

jiffypop45 posted:

If I'm trying to convert a class function to a global function that has friendship to the class, am I going to be more or less required to pass the object by reference to every single one of those functions? This seems like a rather pedantic exercise for the sake of understanding friendship :psyduck:
Where the heck are you getting a graduate degree?

Star War Sex Parrot
Oct 2, 2003

Soylent Pudding posted:

I'm familiar with overloading, but my insert function is only supposed to take in a Comparable. The overall problem is that the given input string will sometimes have to be parsed into integer, sometimes to string, and sometimes to any other data type our professor deems appropriate. So what I really need to figure out is how to assign the parsed value into my Comparable var.
You generally need to make your templated data structures as type-agnostic as possible. That means making as few assumptions about valid operators, member functions, etc. as possible about your stored data type. I'm curious: does the constructor for this class include a comparison functor as a parameter or do you just have to assume that > and < will work (hence the Comparable template typename).

Perhaps you should ask your instructor/a TA about how to approach this issue for your assignment.

edit: also are you saying that input could be "3 4 2 9 38 10 1" which would insert int into your BST, while "Matthew Mark Luke John" which would insert std::string into your BST?

Star War Sex Parrot fucked around with this message at 04:29 on Apr 2, 2015

Star War Sex Parrot
Oct 2, 2003

So the issue at the moment is that when you're tokenizing your input string, you're attempting to make your token (c) represent the type of your template parameter. This seems like the incorrect approach to me because substr is always gonna spit out another string. I'd tokenize to strings first, and then work from there.

Star War Sex Parrot
Oct 2, 2003

Alternatively, after thinking about it a bit more: rather than tokenizing to std::string using substr(), use a std::istringstream and >> to extract the data in the correct format (either int or std::string). My hunch is that if you >> into a Comparable object then things will work out nicely as long as the template parameter type is int or std::string, but I can't say for certain without mucking with your code a bit.

See the example at the bottom of this page for inspiration.

Star War Sex Parrot fucked around with this message at 05:23 on Apr 2, 2015

Star War Sex Parrot
Oct 2, 2003

What's the scope of #define macros in C? I'm working on embedded stuff and see a lot of macros defined at the top of .c files, and just want to be sure those won't interfere with stuff I'm writing elsewhere in the project. I'm guessing that if the macros are defined in headers, then they'll be visible anywhere that includes them, but if they're in .c files they're restricted to that file? I'm not quite sure how the preprocessor parses #define.

I suppose I could do a quick test...

Star War Sex Parrot
Oct 2, 2003

Suspicious Dish posted:

When you use #include, the preprocessor literally just copy/pastes the included file into yours at that location.
Yep, I'm glad I at least understood this preprocessor directive's behavior correctly.

The Laplace Demon posted:

Also note that if they occur above any #include directives, they're visible within the #included files too (and potentially re#defined to another value or #undefined entirely...)
Which is probably why this made sense to me.

Thanks everyone!

Star War Sex Parrot
Oct 2, 2003

Soylent Pudding posted:

Could someone elaborate on this please? I've done this (and seen my professors do this) for all my projects so far.
using namespace std; is super duper lazy and pollutes your namespace with symbols from the STL. For one, you don't know what symbols you'll end up trying to redefine until the compiler yells at you, and you're causing potential issues down the line. Even if you picked a symbol name that was safe in C++11/14, who's to say that might become an STL symbol in C++17, etc.?

I probably didn't explain it as eloquently or technically correct as stuff you'll find on :google:, but it's bad practice and you shouldn't do it.

Star War Sex Parrot
Oct 2, 2003

Diametunim posted:

Thanks for pointing me in the right direction. Why would you implement it this way vs a standard 1D array?
What do you mean by "standard"? The type used to keep track of a dynamically allocated array is a pointer, and since the type being stored in the array is also pointers, you end up with a declaration of stNode** for your buckets array.

If you're wondering why you can't do a statically allocated array, my assumption is that because you have two bucket count variables (an initial and current) you'll have to resize and rehash your table based on the load factor. You'll want to use dynamic allocation since you're not dealing with a compile-time constant for the array size.

Edit: the copy constructor and assignment operator being disallowed gives me a :raise: feeling. I hope your instructor has you implement them at some point, since they're pretty critical to get right in a C++-based data structures course. They're also using a pre-C++11 method to disallow it (private member) as opposed to declaring it as = delete. That's not important but maybe you find that interesting :)

Star War Sex Parrot fucked around with this message at 20:47 on Apr 26, 2015

Star War Sex Parrot
Oct 2, 2003

roomforthetuna posted:

I've never seen anything that tries to *teach* debugging techniques. It's a really weird gap in CS curricula, interview tests, etc.
Are you talking an entire course devoted to debugging techniques? I've encountered several programming courses throughout my degree that taught different methods depending on the language and IDE: break points, copious printing to the console, stepping into/through code, Google Test for unit testing, dynamic analysis with Valgrind and AddressSanitizer, as well as entire courses devoted to software engineering best practices (especially testing). I wouldn't say there was a huge gap in my CS curricula. My suspicion is that it depends on the school and the degree.

Adbot
ADBOT LOVES YOU

Star War Sex Parrot
Oct 2, 2003

roomforthetuna posted:

I'm sure it depends on the place. It seems like yours is the exceptional case, because internet questions about why poo poo's not working are clearly coming from people who haven't been taught any way to debug, but I suppose that might just be selection bias, maybe 95% of places teach that stuff and you just don't see any questions from those people because they can all solve their own "why doesn't this work" problems.
Yep, I'm leaning toward selection bias. Speaking as a programming tutor for my university (helping students who are going through the classes I described earlier) it's more that the people who are asking for help generally just aren't strong programmers or debuggers yet. It takes time. It could come across as not knowing about debugging tools at all, but instead I think that the students aren't sure how to apply them if the don't understand the problem they're trying to solve in the first place. I also have to remind myself that the students asking for help typically aren't hobbyist programmers, so they're probably being exposed to these concepts for the first time.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply