|
Say Something... |
AMCerasoli
Member #11,955
May 2010
|
bamccaig said: Sure, but the API that you've defined above is more verbose and more difficult to read than the raw SQL is. Well I don't really see it that way. Quote: It's also less functional. At least be careful not to introduce SQL injection vulnerabilities in your API. Actually one of the main features of implementing all these functions is to filter the strings that really matter to check SQL Injection, etc. The checking happens inside the Database class automatically. Quote: int foo = stack<int>::get(glue, glue->state(), 0); Yes but I need to type <int> so it's practically the same than creating a separated function for each data type. Now I'm using boost::any like this: int QueryResult::getInt(std::string key, int rowNum){ return boost::any_cast<int>(resTable[key][rowNum]); } double QueryResult::getDouble(std::string key, int rowNum){ return boost::any_cast<double>(resTable[key][rowNum]); } std::string QueryResult::getText(std::string key, int rowNum){ return boost::any_cast<std::string>(resTable[key][rowNum]); } Having different functions for each type is not so bad, as Edgar suggested.
|
Thomas Fjellstrom
Member #476
June 2000
|
AMCerasoli said: Yes but I need to type <int> so it's practically the same than creating a separated function for each data type. I have to create a separate struct for each one... but there's a reason (complex issues with detecting the use of std::shared_ptr, and such things, while still having access to the wrapped type) that I went with the struct and partial specialization over just overridden methods. I think its possible that you can just do: int foo = stack::get(); and have the compiler figure it out based on the return type, but I'm iffy on that one. Oh but if you mean separately named functions, yeah, I can't do that in my code. I don't want to duplicate some very complex template magic based on the types.. so the inside get/put stack stuff has to be templated the way it is. -- |
AMCerasoli
Member #11,955
May 2010
|
Thomas Fjellstrom said: I think its possible that you can just do: int foo = stack::get(); and have the compiler figure it out based on the return type, but I'm iffy on that one. I have been reading and reading about that but it seems that is not possible to make a template function, for example, deduce the type by its return value. There was a guy that did something with a struct or something like that but it doesn't matter, that won't stop me, there are too many things to do right now. If I see that I'll need just one function then I'll try to come up with something if it's actually possible. Quote: Oh but if you mean separately named functions, yeah, I can't do that in my code. I don't want to duplicate some very complex template magic based on the types.. so the inside get/put stack stuff has to be templated the way it is. Yes I can understand that. I think in my case I don't really need just one function let's see, after all those will always be those basic types. Edit:Inserting data example: insData_t data = { {"email", "email@email.com"}, {"password", "1234"}, {"creationDate", 354534563} }; db.insert("playes", data);
|
Slartibartfast
Member #8,789
June 2007
|
AMCerasoli said: I have been reading and reading about that but it seems that is not possible to make a template function, for example, deduce the type by its return value. There was a guy that did something with a struct or something like that but it doesn't matter, that won't stop me, there are too many things to do right now. You mean something like this: 1#include <iostream>
2#include <assert.h>
3
4using namespace std;
5
6class AnyType
7{
8 typedef enum _Type{
9 DOUBLE,
10 INT
11 } TYPE;
12
13 union{
14 double dDouble;
15 int iInt;
16 };
17 TYPE eType;
18
19public:
20
21 AnyType(double d):dDouble(d),eType(DOUBLE){}
22 AnyType(int i):iInt(i),eType(INT){}
23
24 operator double()
25 {
26 assert(DOUBLE == eType);
27 return dDouble;
28 }
29
30 operator int()
31 {
32 assert(INT == eType);
33 return iInt;
34 }
35};
36
37AnyType foo()
38{
39 return 5.5;
40}
41
42int main()
43{
44 double dFoo = foo();
45
46 cout <<dFoo<<endl;
47
48 int iFoo = foo();
49
50 cout <<iFoo;
51
52 return 0;
53}
Output: 5.5 Assertion failed! Program: CPPPlayGround.exe File: ..\CPPPlayGround\main.cpp, Line 32 Expression: INT == eType This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. ? ---- |
AMCerasoli
Member #11,955
May 2010
|
Slartibartfast said: You mean something like this: No he was using templates, but I didn't pay attention so I could be wrong. He was trying to make the template function deduce the type by its return value.
|
bamccaig
Member #7,536
July 2006
|
I too got bored. 1#include <iostream>
2#include <sstream>
3#include <string>
4
5#define protected protected:
6#define public public:
7
8// hpp
9namespace bam
10{
11 class variant
12 {
13 protected enum type {BOOL, DOUBLE, FLOAT, INT, NIL, STRING};
14
15 protected union { bool b_; double d_; float f_; int i_; };
16 protected std::string s_;
17 protected variant::type t_;
18
19 protected template<typename T> T number_(void) const;
20
21 public variant(void);
22 public variant(const bool &);
23 public variant(const char * const &);
24 public variant(const double &);
25 public variant(const float &);
26 public variant(const int &);
27 public variant(const std::string &);
28
29 public operator bool(void) const;
30 public operator double(void) const;
31 public operator float(void) const;
32 public operator int(void) const;
33 public operator std::string(void) const;
34
35 public variant operator +(const variant &) const;
36 public variant operator -(const variant &) const;
37 public variant operator *(const variant &) const;
38 public variant operator /(const variant &) const;
39 public variant operator %(const variant &) const;
40
41 public variant operator &(const variant &) const;
42 public variant operator |(const variant &) const;
43 public variant operator ^(const variant &) const;
44 public variant operator <<(const variant &) const;
45 public variant operator >>(const variant &) const;
46
47 public bool nil(void) const;
48 public bool num(void) const;
49 public bool str(void) const;
50 };
51}
52
53// cpp
54namespace bam
55{
56 variant::variant(void): t_(variant::NIL) {}
57 variant::variant(const bool & b):b_(!!b), t_(variant::BOOL) {}
58 variant::variant(const char * const & s):s_(s), t_(variant::STRING) {}
59 variant::variant(const double & d):d_(d), t_(variant::DOUBLE) {}
60 variant::variant(const float & f):f_(f), t_(variant::FLOAT) {}
61 variant::variant(const int & i):i_(i), t_(variant::INT) {}
62 variant::variant(const std::string & s):s_(s), t_(variant::STRING) {}
63
64 template<typename T>
65 T variant::number_(void) const
66 {
67 switch(this->t_)
68 {
69 case variant::NIL:
70 break;
71 case variant::BOOL:
72 return (T)this->b_;
73 case variant::DOUBLE:
74 return (T)this->d_;
75 case variant::FLOAT:
76 return (T)this->f_;
77 case variant::INT:
78 return (T)this->i_;
79 case variant::STRING:
80 T v;
81 std::stringstream ss(this->s_);
82
83 ss >> v;
84
85 return v;
86 }
87
88 return (T)0;
89 }
90
91 variant::operator bool(void) const
92 {
93 return !!this->number_<int>();
94 }
95
96 variant::operator double(void) const
97 {
98 return this->number_<double>();
99 }
100
101 variant::operator float(void) const
102 {
103 return this->number_<float>();
104 }
105
106 variant::operator int(void) const
107 {
108 return this->number_<int>();
109 }
110
111 variant::operator std::string(void) const
112 {
113 std::stringstream ss;
114
115 switch(this->t_)
116 {
117 case variant::NIL:
118 break;
119 case variant::BOOL:
120 ss << this->b_;
121 break;
122 case variant::DOUBLE:
123 ss << this->d_;
124 break;
125 case variant::FLOAT:
126 ss << this->f_;
127 break;
128 case variant::INT:
129 ss << this->i_;
130 break;
131 case variant::STRING:
132 ss << this->s_;
133 break;
134 }
135
136 return ss.str();
137 }
138
139 /*
140 * h4x: It doesn't make much sense to do arithmetic on strings.
141 * Strings become nil. See bitwise operators for concatenation.
142 */
143
144 variant variant::operator +(const variant & v) const
145 {
146 switch(this->t_)
147 {
148 case variant::NIL:
149 case variant::STRING:
150 break;
151 case variant::BOOL:
152 return variant(this->b_ + (bool)v);
153 case variant::DOUBLE:
154 return variant(this->d_ + (double)v);
155 case variant::FLOAT:
156 return variant(this->f_ + (float)v);
157 case variant::INT:
158 return variant(this->i_ + (int)v);
159 }
160
161 return variant();
162 }
163
164 variant variant::operator -(const variant & v) const
165 {
166 switch(this->t_)
167 {
168 case variant::NIL:
169 case variant::STRING:
170 break;
171 case variant::BOOL:
172 return variant(this->b_ - (bool)v);
173 case variant::DOUBLE:
174 return variant(this->d_ - (double)v);
175 case variant::FLOAT:
176 return variant(this->f_ - (float)v);
177 case variant::INT:
178 return variant(this->i_ - (int)v);
179 }
180
181 return variant();
182 }
183
184 variant variant::operator *(const variant & v) const
185 {
186 switch(this->t_)
187 {
188 case variant::NIL:
189 case variant::STRING:
190 break;
191 case variant::BOOL:
192 return variant(this->b_ * (bool)v);
193 case variant::DOUBLE:
194 return variant(this->d_ * (double)v);
195 case variant::FLOAT:
196 return variant(this->f_ * (float)v);
197 case variant::INT:
198 return variant(this->i_ * (int)v);
199 }
200
201 return variant();
202 }
203
204 variant variant::operator /(const variant & v) const
205 {
206 switch(this->t_)
207 {
208 case variant::NIL:
209 case variant::STRING:
210 break;
211 case variant::BOOL:
212 return variant(this->b_ / (bool)v);
213 case variant::DOUBLE:
214 return variant(this->d_ / (double)v);
215 case variant::FLOAT:
216 return variant(this->f_ / (float)v);
217 case variant::INT:
218 return variant(this->i_ / (int)v);
219 }
220
221 return variant();
222 }
223
224 variant variant::operator %(const variant & v) const
225 {
226 switch(this->t_)
227 {
228 case variant::NIL:
229 case variant::BOOL:
230 case variant::DOUBLE:
231 case variant::FLOAT:
232 case variant::STRING:
233 break;
234 case variant::INT:
235 return variant(this->i_ % (int)v);
236 }
237
238 return variant();
239 }
240
241 /*
242 * h4x: Bitwise operations on a variant type is silly. Overload those
243 * for string-wise concatenation instead.
244 */
245
246 variant variant::operator &(const variant & v) const
247 {
248 switch(this->t_)
249 {
250 case variant::NIL:
251 break;
252 case variant::BOOL:
253 case variant::DOUBLE:
254 case variant::FLOAT:
255 case variant::INT:
256 case variant::STRING:
257 return (std::string)*this + (std::string)v;
258 }
259
260 return variant();
261 }
262
263 variant variant::operator |(const variant & v) const
264 {
265 return *this & v;
266 }
267
268 variant variant::operator ^(const variant & v) const
269 {
270 return *this & v;
271 }
272
273 variant variant::operator <<(const variant & v) const
274 {
275 return *this & v;
276 }
277
278 variant variant::operator >>(const variant & v) const
279 {
280 return *this & v;
281 }
282
283 bool variant::nil(void) const { return this->t_ == variant::NIL; }
284 bool variant::num(void) const { return !this->nil() && !this->str(); }
285 bool variant::str(void) const { return this->t_ == variant::STRING; }
286}
287
288typedef bam::variant my;
289typedef bam::variant variant;
290
291// main
292int main(int, char * [])
293{
294 my nv;
295 my bv((bool)5);
296 my dv((double)5);
297 my fv((float)5);
298 my iv(5);
299 my csv("5 is a number");
300 my sv(std::string("five is also a number"));
301
302 bv = bv + variant(2.2);
303 dv = dv + variant(2.2);
304 fv = fv + variant(2.2);
305 iv = iv + variant(2.2);
306
307 csv = csv & my(".");
308 sv = sv | my(".");
309
310 bool b = bv;
311 double d = dv;
312 float f = fv;
313 int i = iv;
314 std::string cs = csv;
315 std::string s = sv;
316
317 double db = bv;
318 float fb = bv;
319 int ib = bv;
320 std::string sb = bv;
321
322 bool bd = dv;
323 float fd = dv;
324 int id = dv;
325 std::string sd = dv;
326
327 bool bf = fv;
328 double df = fv;
329 int if_ = fv;
330 std::string sf = fv;
331
332 bool bi = iv;
333 double di = iv;
334 float fi = iv;
335 std::string si = iv;
336
337 bool bcs = csv;
338 double dcs = csv;
339 float fcs = csv;
340 int ics = csv;
341
342 bool bs = sv;
343 double ds = sv;
344 float fs = sv;
345 int is = sv;
346
347 std::cout
348 << "nv is nil=" << nv.nil() << "\n"
349 << "bv is nil=" << bv.nil() << "\n"
350 << "dv is nil=" << dv.nil() << "\n"
351 << "fv is nil=" << fv.nil() << "\n"
352 << "iv is nil=" << iv.nil() << "\n"
353 << "csv is nil=" << csv.nil() << "\n"
354 << "sv is nil=" << sv.nil() << "\n"
355 << "b=" << b << "\n"
356 << "d=" << d << "\n"
357 << "f=" << f << "\n"
358 << "i=" << i << "\n"
359 << "cs=" << cs << "\n"
360 << "s=" << s << "\n"
361 << "db=" << db << "\n"
362 << "fb=" << fb << "\n"
363 << "ib=" << ib << "\n"
364 << "sb=" << sb << "\n"
365 << "bd=" << bd << "\n"
366 << "fd=" << fd << "\n"
367 << "id=" << id << "\n"
368 << "sd=" << sd << "\n"
369 << "bf=" << bf << "\n"
370 << "df=" << df << "\n"
371 << "if=" << if_ << "\n"
372 << "sf=" << sf << "\n"
373 << "bi=" << bi << "\n"
374 << "di=" << di << "\n"
375 << "fi=" << fi << "\n"
376 << "si=" << si << "\n"
377 << "bcs=" << bcs << "\n"
378 << "dcs=" << dcs << "\n"
379 << "fcs=" << fcs << "\n"
380 << "ics=" << ics << "\n"
381 << "bs=" << bs << "\n"
382 << "ds=" << ds << "\n"
383 << "fs=" << fs << "\n"
384 << "is=" << is << "\n"
385 << std::endl;
386
387 return 0;
388}
g++ -W -Wall -Wextra variant.cpp ./a.exe nv is nil=1 bv is nil=0 dv is nil=0 fv is nil=0 iv is nil=0 csv is nil=0 sv is nil=0 b=1 d=7.2 f=7.2 i=7 cs=5 is a number. s=five is also a number. db=2 fb=2 ib=2 sb=2 bd=1 fd=7.2 id=7 sd=7.2 bf=1 df=7.2 if=7 sf=7.2 bi=1 di=7 fi=7 si=7 bcs=1 dcs=5 fcs=5 ics=5 bs=0 ds=0 fs=0 is=0 (Barely tested...) -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
AMCerasoli
Member #11,955
May 2010
|
What the... I'm not able to read! what is going on there? I will need to read that for some time.
|
Thomas Fjellstrom
Member #476
June 2000
|
That's not too bad bambams, reminds me of Perl's SV type. I was thinking of going with something like that in luaglue, but I wanted everything to inline at compile time, and do as little type checking as possible at run time. I managed to succeed at that. The only time types need to be checked is when certain types get put onto the lua stack (statically allocated objects, calls from lua, and certain other types, when ever it doesn't know the incoming associated LuaGlue class). Quote: What the... I'm not able to read! what is going on there? I will need to read that for some time. Is it the excessive public specifiers? -- |
bamccaig
Member #7,536
July 2006
|
Thomas Fjellstrom said: Is it the excessive public specifiers? I'm sort of on the fence with that still, but meh. Replaced with macros to make it more readable. It's a little bit of an ugly solution, but at the same time I find that using essentially labels for that is also ugly. Append: Speaking of Perl, I wonder what would happen if I rename the class to my. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Thomas Fjellstrom
Member #476
June 2000
|
Why are you even doing that? That's stupid java bullcrap. -- |
bamccaig
Member #7,536
July 2006
|
Thomas Fjellstrom said: Why are you even doing that? That's stupid java bullcrap. It's not exclusive to Java (C# uses the same syntax, and I'm sure others do too), and it's not overly stupid either. I already said why: I find it awkward to use "labels" as C++ does for that. Normally I don't do that, but it has been a while since I've written C++ and I decided to give it a taste. I probably won't be able to do it since most people and projects would probably strongly object to it. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
AMCerasoli
Member #11,955
May 2010
|
I made pizza!! {"name":"608548","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/5\/05ed7ea6c01623c958ca5096e85a1197.jpg","w":600,"h":704,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/5\/05ed7ea6c01623c958ca5096e85a1197"}
|
l j
Member #10,584
January 2009
|
I find writing the public modifier over and over again far more awkward than a label.
|
Thomas Fjellstrom
Member #476
June 2000
|
Good thing its not a label though. Its an access specifier! -- |
bamccaig
Member #7,536
July 2006
|
taron said: I find writing the public modifier over and over again far more awkward than a label. It would make better sense if it was a block and if the order of declarations didn't matter. This is particularly what I find awkward: 1// Contrived example...
2class A
3{
4protected:
5 int x_;
6
7public:
8 void f() { this->x_++; }
9
10protected:
11 void g() { for(int i=0; i<3; i++) this->f(); }
12
13public:
14 void h() { if(this->x_ < 10) this->g(); }
15};
You cannot reorder the definitions because they depend on one another so you have to go back and forth with the access specifiers. Which to me is just ugly. If your class is quite large too it could push the access specifiers right off of the screen that you're reading, leaving you to wonder what applies to what you're seeing. Trust me, I write C# for a living, and using access specifiers on all members isn't at all bad. If your editor doesn't suck then it should be easy to manage. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Thomas Fjellstrom
Member #476
June 2000
|
The only reason you have to go back and forth like that is because you need to keep binary compatibility. That is it afaik. -- |
Gideon Weems
Member #3,925
October 2003
|
pkrcel
Member #14,001
February 2012
|
He is Armando, after all. Nice pizza....even if I see a bit too much mais @bam What are you talking about? I mean why you wrote the example a that? As far as I know (which is anot much) you can safely move the definition of (say) x_ at the end of the class and it should compile...I can't see the point. It is unlikely that Google shares your distaste for capitalism. - Derezo |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Geez Armando, that pizza looks worse than the Allegro logo I put up! It looks luke warm and left out on the counter too long.... My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Slartibartfast
Member #8,789
June 2007
|
Generally C++ classes should look like 1class Name
2{
3public:
4 // public interface of class
5 void Foo();
6 virtual void Bar();
7
8protected:
9 // protected interface of class - its interface with its inheritors
10 virtual double _GetFooness();
11 double _SafeBar();
12
13private:
14 // internal implementation
15 void _DoFoo();
16 void _DoBar();
17
18private:
19 // private members
20 double m_dX;
21 double m_dY;
22}
You group them according to access in order to make the class coherent - first its public interface (so if I use the class, I look at just the first block), then the protected interface (so if I inherit from the class, I look at the first two blocks), then the private interface (if I'm editing the class, I look here) and finally the members (which are all private, since public/protected members are a horrible thing in most cases . They are last because you only care about those if you are editing the class itself) bamccaig said: You cannot reorder the definitions because they depend on one another so you have to go back and forth with the access specifiers. You don't need to reorder them because you implement them in your source file, not your header file. Quote: If your class is quite large too it could push the access specifiers right off of the screen that you're reading, leaving you to wonder what applies to what you're seeing. You write them in a specific order according to the conventions, there's no room for misunderstandings. Just the name of the function should be sufficient to identify the access. Quote: Trust me, I write C# for a living, and using access specifiers on all members isn't at all bad. Trust me, I write C++ for a living, and using access specifiers only when they are needed is pretty good ---- |
bamccaig
Member #7,536
July 2006
|
Slartibartfast said: You group them according to access in order to make the class coherent - first its public interface (so if I use the class, I look at just the first block), then the protected interface (so if I inherit from the class, I look at the first two blocks), then the private interface (if I'm editing the class, I look here) and finally the members (which are all private, since public/protected members are a horrible thing in most cases . They are last because you only care about those if you are editing the class itself) I agree with everything you said. Slartibartfast said: You don't need to reorder them because you implement them in your source file, not your header file. For production code you do this, mainly because of language limitations. However, the language allows you to inline it for simpler programs, and in doing so imposes the order of members on you. Since the language carries that limitation I choose to seek out a friendly way to workaround it all of the time. Like I said, I don't normally do that. I was just trying it out. It turns out that once I split the code into separate files (I figure I might as well create a repo on GitHub for it) it didn't work anymore. I'm not sure why the preprocessor/compiler doesn't like that macro when split into separate files (I can't figure it out), but it doesn't seem to anyway. Slartibartfast said: You write them in a specific order according to the conventions, there's no room for misunderstandings. Just the name of the function should be sufficient to identify the access. I agree with this as well, however, I also know that you can't trust other people to do this so in the real world this falls apart unless maybe you happen to be a part of a competent and strict team. Slartibartfast said: Trust me, I write C++ for a living, and using access specifiers only when they are needed is pretty good I also hate that it borrows label-syntax. It just seems like such a hack... I wonder what made them come up with that solution... I would have probably preferred a block-like syntax: public {} protected {} private {}. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
AMCerasoli
Member #11,955
May 2010
|
Gideon Weems said: I need to know this: Where are you from? Spain (my mother from Spain my father from Italy). pkrcel said: He is Armando, after all. Nice pizza....even if I see a bit too much mais Yhea I'm pretty much armando things all the time, and yhea I like maíz! . Thank you. Edgar Reynaldo said: Geez Armando, that pizza looks worse than the Allegro logo I put up! It looks luke warm and left out on the counter too long... Oh, if I could send food through internet I would, but sorry it's not possible right now. Yhea, it was delicious. Took me like 20 horrible pizzas to reach that point .
|
Gideon Weems
Member #3,925
October 2003
|
Slartibartfast
Member #8,789
June 2007
|
bamccaig said: For production code you do this, mainly because of language limitations. However, the language allows you to inline it for simpler programs, and in doing so imposes the order of members on you. The language allows it, that doesn't mean you have to use it. In practice I find that the only cases where I do that are simple enough that public functions don't depend on protected/private function, and usually unimportant enough that even if they did I wouldn't bother with access specifiers and just set everything to public (i.e. something like a playground project, a proof of concept etc.) Quote: I also know that you can't trust other people to do this so in the real world this falls apart unless maybe you happen to be a part of a competent and strict team.
I have a strict team, and if you do not adhere to the conventions you'll be scolded and have to fix it after the first Code Review. Quote: I also hate that it borrows label-syntax. It just seems like such a hack... I wonder what made them come up with that solution... I would have probably preferred a block-like syntax: public {} protected {} private {}. There are cases for an against both options, for example the block syntax defines scope whenever it is used, however the access specifiers do not specify scope (you can use something in the "public scope" from the "private scope" and the other way around as well). Overall not a really important issue, it is okay to just stick with what works right now ---- |
William Labbett
Member #4,486
March 2004
|
I need a pizza information. Where's Trent ?
|
|
|