|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
Thanks for the quick response. I am off to bed now so I will look at it late in detail but I propabaly wont profit much from it. I am not using teamliquid as my lazymans-google, I am genuinely incompetent when it comes to these examples without much explaination. THey remind me of mathematics where I am on the opposing side and understand all the cryptic solutions and explanations. Here I fail at such simple things as "what does '*this'" exactly represents in the example? I have a guess, but I am just not sure. I know what "this->" is used for in code. "rhs/lhs" is also clear. For the article: I will make sure to do my best learn and follow theese guidelines but if it was a small hint that what I am trying to do isnt apropriate/is stuoid: sadly, I am not the one who made these exercise . In the same assignment we are asked to keep a track of all DVDs that are present in the videoshop, not in the videoshop-class itself but in the dvd-class via a static. Propably makes sense programming wise since you can keep track of it by increasing/decreasing it in the constructor/deconstructor but for us newbies it sure sound pretty weird, especially if we already have all DVDs that are in the shop listed in a single vector and could use vector.size. Well there are propably some benfits for doing it his way, but he never told us and to introduce newcomers to classvariables there sure is a less confusing example. Anyways, good night and thanks fpr the help.
|
On February 05 2015 09:27 Artesimo wrote:Thanks for the quick response. I am off to bed now so I will look at it late in detail but I propabaly wont profit much from it. I am not using teamliquid as my lazymans-google, I am genuinely incompetent when it comes to these examples without much explaination. THey remind me of mathematics where I am on the opposing side and understand all the cryptic solutions and explanations. Here I fail at such simple things as "what does '*this'" exactly represents in the example? I have a guess, but I am just not sure. I know what "this->" is used for in code. "rhs/lhs" is also clear. For the article: I will make sure to do my best learn and follow theese guidelines but if it was a small hint that what I am trying to do isnt apropriate/is stuoid: sadly, I am not the one who made these exercise  . In the same assignment we are asked to keep a track of all DVDs that are present in the videoshop, not in the videoshop-class itself but in the dvd-class via a static. Propably makes sense programming wise since you can keep track of it by increasing/decreasing it in the constructor/deconstructor but for us newbies it sure sound pretty weird, especially if we already have all DVDs that are in the shop listed in a single vector and could use vector.size. Well there are propably some benfits for doing it his way, but he never told us and to introduce newcomers to classvariables there sure is a less confusing example. Anyways, good night and thanks fpr the help. 
this is a keyword that refers to the object that called the function. I create an object x. When I call the set function on the x object 'this' is the x object. The set function sets the value field of the object to whatever was passed to the function because this refers to the value field of whatever object is calling the set function.
Example x = new Example(); x.set( 5 );
class Example { int value;
// constructor Example() { int value = 0; }
void set( int value ) { this.value = value; } }
|
@arte i will put aside the notion of templates, and speak strictly of classes:
all non-static member functions (note that a friend declaration is not a member function declaration) of a class admit an implicit argument: a pointer to an object of said type on which the member function was called. this pointer is accessed through the this-keyword. contrast:
class type { int only_member; //only member can access only_member for now public: void member() //function can access and call member { //use this } };
void function(type* that) { //use public stuff in that }
... //eventually type* this_and_that = new type; this_and_that->member(); //as this function(this_and_that); //as that
...
a member function can have qualifiers (const, reference, volatile). these apply to the implicit this pointer of the function. in this following snippet neither const_member, nor const_function can call member. recall that member's implicit argument is type*, however const_member and const_function have access to const type* this and const type* that respectively, which can't be passed as the type* argument of member (note that the reverse is ok).
class type { public: void member() //neither const_member or const_funtion can {} //call this member function even though it is accessible to both //recall that function() from previous snippet could call member. void const_member() const //const function can access and call this member function { //use const this } };
void const_function(const type* that) { //use public const stuff in that }
the friend keyword controls access to class members. by declaring function and const_function friends they are no longer restricted to publicly declared members of that, but can also access private and protected members. making them approximately equivalent to their member function counterparts.
the unary * operator is called the dereference operator, and (when called on a pointer) returns the "l-value equivalent to the value of the pointer address". if you dereference the this pointer inside of a member-function of type, result of this expression is an l-value (type&) bound to the value at the address of this. simlarly for const this and const type&.
a compilable example where the equivalence of the address of this and that is shown in console, the functions are declared as friend to access privately declared members, as well as const and non const usage of a member variable (note that assigning value in either of the const functions would not have compiled, since you can't bind an const int& to the lhs argument (int&) of the = operator for ints). + Show Spoiler +#include<iostream>
using std::cout; using std::endl;
class type { friend void function(type*); friend void const_function(const type*); int value{0}; public: void member() { cout<<"type::member():\n"; cout<<"\taddress of this: "<<this<<endl; int new_value=this->value-1; cout<<"\tassigning value: "<<this->value<<" -> "<<new_value<<endl; this->value=new_value; } void const_member() const { cout<<"type::const_member():\n"; cout<<"\taddress of const this: "<<this<<endl; cout<<"\tconst value: "<<this->value<<endl; } };
void function(type* that) { cout<<"function(type* that):\n"; cout<<"\taddress of that: "<<that<<endl; int new_value=that->value+1; cout<<"\tassigning value: "<<that->value<<" -> "<<new_value<<endl; that->value=new_value; }
void const_function(const type* that) { cout<<"const_function(const type that*):\n"; cout<<"\taddress of const that: "<<that<<endl; cout<<"\tconst value: "<<that->value<<endl; }
int main() { type* t0=new type;
cout<<"\n--------------- functions ---------------\n\n"; function(t0); const_function(t0); cout<<"\n-----------------------------------------\n\n";
cout<<"\n------------ member functions -----------\n\n"; t0->member(); t0->const_member(); cout<<"\n-----------------------------------------\n\n";
delete t0; } + Show Spoiler [output] +[jeh@gimli tl]$ make g++ -c -std=c++14 -I. -fdiagnostics-color tl.cpp g++ -o tl tl.o rm -rf *.o [jeh@gimli tl]$ ./tl
--------------- functions ---------------
function(type* that): address of that: 0x845010 assigning value: 0 -> 1 const_function(const type that*): address of const that: 0x845010 const value: 1
-----------------------------------------
------------ member functions -----------
type::member(): address of this: 0x845010 assigning value: 1 -> 0 type::const_member(): address of const this: 0x845010 const value: 0
-----------------------------------------
|
Thanks Blitzkrieg0, your explanation helped a lot.
@nunez: sorry, I am not sure what to take out of your post. the thing with the class variable was just an example for how our prof confuses us, the part itself I managed to accomplish and I think I understand it, therefore I am not sure what to learn from it. Maybe I am just missing the point, but anyways, thank you a lot for you effort, I really appreciate it.
Sadly, I am still stuck with overloading the += operator.
class X { X& operator+=(const X& rhs) { // actual addition of rhs to *this return *this; } };
Given Manit0u's codeexample, I am in my class videoshop, in it I want to use the overloaded operator, to add a new DVD to my vector "dvd" where the DVDs are stored. Therefore:
Header: friend Videothek& operator+=(Videothek&, string);
.ccp: Videothek& operator+=(Videothek&, string dvdName) { dvd.pushback(new DVD(dvdName)); }
However, it says that "dvd" is not defined, which I dont understand why, since it is an attribute of the videothek-class in which the overload is happening. This is what I initially tried before asking for help and now that I have a bit more knowlegde, I think it is the closest to the right solution that I got, or am I totally wrong? And even if I am totally wrong, can someone still explain me why the function suddenly "forgot" that there is an attribute "dvd"?
|
you're declaring the operator as a non-member function, and not a member function, thus dvd is not defined (how could a non-member function figure out which class scope the programmer would like it to be in? mind reading?). here is small example declaring an operator as a member function. in the member funtion body you are in type:: scope and value is defined. (caveat, maybe i misunderstood your code and you just cut out the class Whatever{ ... }; part, and showed only the definition): + Show Spoiler [code] +#include<string> #include<utility>
using namespace std;
class type { string value; public: //ok this is fine type& operator+=(string rhs) { value+=move(rhs); return *this; } };
int main() { type t0; t0+=string("hello"); }
here is a naive attempt as declaring the operator as a non-member function instead, however this will fail to compile, because value is a private member, and the non-member function does not have access to it. + Show Spoiler [fail code] +#include<string> #include<utility>
using namespace std;
class type { string value; public: };
type& operator+=(type& lhs,string rhs){ lhs.value+=move(rhs); //not allowed, value is a private member return lhs; //and this non-member funciton does not have access }
int main() { type t0; t0+=string("hello"); }
this can be remedied by declaring the non-member function as a friend function of type; this gives it access to both protected and private members. in the non-member function body we are not in any class scope, and we have to access value through lhs like so: + Show Spoiler [code] +#include<string> #include<utility>
using namespace std;
class type { friend type& operator+=(type&,string); string value; public: };
type& operator+=(type& lhs,string rhs){ lhs.value+=move(rhs); return lhs; }
int main() { type t0; t0+=string("hello"); }
in case i misread your code and you are having trouble defining a member function outside the class defininition then i will provide a small example of this as well: + Show Spoiler [caveat] +#include<string> #include<utility>
using namespace std;
class type { string value; public: type& operator+=(string rhs); //declaration };
type& type::operator+=(string rhs) //definition, note the type:: scope { value+=move(rhs); return *this; } int main() { type t0; t0+=string("hello"); }
|
Hold on, got an Idea + Show Spoiler +Thanks for the response. I indeed cut the header part from my post(now I added it, I already set it as friend and knew what that does), but it still wont cut: friend Videothek& operator+=(Videothek&, string);
If I do it like this: Videothek& operator+=(Videothek& dvd, string dvdName) { dvd.pushback(new DVD(dvdName)); return dvd; }
dvd gets handled as a parameter for the function and .push_back wont work with it. At this point I am just guessing.
|
:O
+ Show Spoiler [stab in dark] +Videothek& operator+=(Videothek& videothek, string dvdName) { videothek.dvd.push_back(new DVD(dvdName)); //ought to use std::move(dvdName) instead return videothek; } post the Videothek definition if you need more accurate feedback.
|
haha nunez . Just as I wrote the last post, it hit me- I got it now, thanks for the help and especially the explanations. I find it somewhat hard to understand the examples that are given on most sites/often they seem complete nonsense to me, lets hope I will get better at this.
Feeling god for the exam tomorrow, sad thing is I am sure I will fail the operator ovleroading though since there are just too many operators to learn them all. Well, 2.0 should be enough, cant have straight 1.0 . Even though I find it quite displeasing that his exams always tend to be: 4.0 - just create 2 classes with constructor, destructor, set, get etc. 3.0 - read in something from a file/include simple inheritance 2.0 - do something with the values/implent a satic classvalue 1.0 - overload operator when in our practical course he never asked us to do anything like static/overloading operators. Hell, even in our lectures we never really talked about what overloading means or static. In the last 3 days I almost learned more than in the past semester, including why he does have a 80% failure quote. Sadly, I will have him again next semester since we have a more strict system here 
Some questions regarding the future: Most of the stuff is "leanr the concept, then your fine", but overloading operators seems to me like the concept changes, regarding the operator. Am I missing some links, or will I have to force myself into memorizing how to overload each operator?
One guy in our semester is pretty skilled in programming, he often teaches us stuff after class and will be the main reason why we will have a lower failure rate then 80% (since the 4.0 criteria is really trivial, but still, you wont believe how our prof holds his lectures). He told me/us a few things like we should (after the exam) get used to use #ifndef and #define instead of #pragmaonce since it is not machine specific. Also we should try to learn not to use "using namepsace::std" since it requires more power because everytime you use a blank space where a std:: should be, the whole namespace-thing gets called and does something(if I remember him correctly). Is this actually true and practical?
|
it is true that there are some interesting idiosyncracies regarding operators, the worst being the syntax for specifying the affix of the increment / decrement operator. however you get a lot free from mathematics: arity, expected semantic, precedence, syntax...
the only important operator you really ought to worry about is the assigment operator, because this ties into copy and move semantics: a most important concept, much more than exotic operator overloads. you need to learn to build a simple shed, before you start adding trap doors, hidden levers, and shark pits.
beyond that operators are merely a way of writing functions, where the expected semantic is a bit more subtle, and you are usually constrained by arity (not in the case of the function call operator).
judging by this thread operator overloading seems difficult to come to terms with, but i can assure you that operator overloading in itself is not. what you are experiencing is different confusions, related to different, distinct concepts joining forces: a daunting monolith. when you get more familiar and are able to consider the concepts seperately, the monolith will fall apart, and the parts will seem manageable. (from afar... when you inspect them closer they consantly fall apart into smaller pieces, change meaning, disappear, or join with another piece, that seemed totally unrelated before).
i never had a problem with #pragma once, and it's shorter to write. why should i care about some imaginary platform? namespaces, like any other tool, requires practice and thought, there is nothing more to be said without a more specific context. it sounds like you are describing a problem with software, and not namespaces, so i suggest you modify your software.
i suggest you don't put up any unecessary barriers, and express yourself the way you feel comfortable with, until necessity reveals itself in a concrete, particular problem.
|
Do you guys spend at least 10 hours in front of computer on a regular basis? If yes, do you get eye twitching? I'm trying to figure out what causes it - too much cola (I've stopped it for the past few days), too much computer screen, lack of sleep, rubbing eyes, etc.
Reducing time in front of computer is hard too as I'm required to spend about 8 hours at work. Any advice?
|
On February 06 2015 04:55 darkness wrote: Do you guys spend at least 10 hours in front of computer on a regular basis? If yes, do you get eye twitching? I'm trying to figure out what causes it - too much cola (I've stopped it for the past few days), too much computer screen, lack of sleep, rubbing eyes, etc.
Reducing time in front of computer is hard too as I'm required to spend about 8 hours at work. Any advice?
The eye twitch is a muscle spasm, which is caused by nerves firing off erroneously. A nerve will have a misfire if there is caffeine or another stimulant such as stress which causes nerves to dump some of its own stimulants. Alternatively, if there is already a lot of activity in the nerve, it may misfire on its own. This boils down to: Caffeine, stress, and light sensitivity.
Cutting out soft drinks will help with long computing sessions. My trick is to take regular walks where I stare into distant cool objects. I also avoid blue and purple lights after dark if using the computer to help keep my eyes adjusted. I tend to take this particular physiological side effect pretty seriously since I'm a pilot.
Many people use f.lux to dim the screen after sundown, which is an option for helping to avoid high energy light. It takes about an hour after seeing a moderately bright blue or purple light to fully adjust back to clear night vision, so avoid doing anything that requires eyesight immediately after computer usage, such as driving.
|
That namespace discussion and the recent one about i++ or ++i makes me wonder if noobs should really bother learning this kind of optimisation, considering we probably still write suboptimal programs anyway. Like today at school, some guy was telling how setting a variable to 0 is slower than using a xor or something. Does any of this really matter, be it right or not, when we still go through any set of variable 3 times more than is needed ? I don't think so, but maybe I'm wrong..
|
That namespace discussion and the recent one about i++ or ++i makes me wonder if noobs should really bother learning this kind of optimisation, considering we probably still write suboptimal programs anyway. Like today at school, some guy was telling how setting a variable to 0 is slower than using a xor or something. Does any of this really matter, be it right or not, when we still go through any set of variable 3 times more than is needed ? I don't think so, but maybe I'm wrong..
I've thought this very question and I wound up comparing it to a Car. What would you rather have a car that is clean runs smoothly and you know will always reliably get you from point A to point B or would you rather have a junker that runs like crap and is questionable as to whether it will get you to your destination... Sub-optimal code is like the latter yea most of the time it runs but it'll cost you more time and money when you try to add on to that code or make adjustments... so basically Sub-optimal code winds up being more maintenance and runs like crap in bigger applications.....
|
On February 06 2015 05:09 RoyGBiv_13 wrote:Show nested quote +On February 06 2015 04:55 darkness wrote: Do you guys spend at least 10 hours in front of computer on a regular basis? If yes, do you get eye twitching? I'm trying to figure out what causes it - too much cola (I've stopped it for the past few days), too much computer screen, lack of sleep, rubbing eyes, etc.
Reducing time in front of computer is hard too as I'm required to spend about 8 hours at work. Any advice? The eye twitch is a muscle spasm, which is caused by nerves firing off erroneously. A nerve will have a misfire if there is caffeine or another stimulant such as stress which causes nerves to dump some of its own stimulants. Alternatively, if there is already a lot of activity in the nerve, it may misfire on its own. This boils down to: Caffeine, stress, and light sensitivity. Cutting out soft drinks will help with long computing sessions. My trick is to take regular walks where I stare into distant cool objects. I also avoid blue and purple lights after dark if using the computer to help keep my eyes adjusted. I tend to take this particular physiological side effect pretty seriously since I'm a pilot. Many people use f.lux to dim the screen after sundown, which is an option for helping to avoid high energy light. It takes about an hour after seeing a moderately bright blue or purple light to fully adjust back to clear night vision, so avoid doing anything that requires eyesight immediately after computer usage, such as driving.
Thank you! I'll delay the decision for computer glasses for now. I guess I'll just wait a little bit and see. I had been drinking a lot of caffeine (well, cola is still caffeine) recently, so that could explain it. I guess nerves need more than a few days pause to adjust. 
On February 06 2015 05:14 Cynry wrote: That namespace discussion and the recent one about i++ or ++i makes me wonder if noobs should really bother learning this kind of optimisation, considering we probably still write suboptimal programs anyway. Like today at school, some guy was telling how setting a variable to 0 is slower than using a xor or something. Does any of this really matter, be it right or not, when we still go through any set of variable 3 times more than is needed ? I don't think so, but maybe I'm wrong..
I think what some people suggest is to prefer readability over premature optimisation. The compiler is pretty good at optimising, so why sacrifice readability from start unless you really need to optimise something? I'm not an expert as some guys here though.
|
On February 06 2015 05:14 Cynry wrote: That namespace discussion and the recent one about i++ or ++i makes me wonder if noobs should really bother learning this kind of optimisation, considering we probably still write suboptimal programs anyway. Like today at school, some guy was telling how setting a variable to 0 is slower than using a xor or something. Does any of this really matter, be it right or not, when we still go through any set of variable 3 times more than is needed ? I don't think so, but maybe I'm wrong.. Performance optimizations like that not only don't matter, they are outright bad unless you profiled your application's performance and determined that doing these things actually improves your performance significantly. Hint: typically you'll find some awful algorithm that hogs all the processing power and can't be improved by more than .00001% by using an xor instead of an assignment.
In the case of ++i over i++ it's just a straight up potential improvement with no downsides unless you specifically need the semantics of i++. Both are equally readable. Whether you should use either of them is another question, but if you use one of them, use ++i.
Performance optimizations at instuction level will usually be done by a moderately intelligent comiler anyways, no need to bother with them.
Let me be clear: Do not attempt to optimize your code for performance unless you actually have a performance problem AND profiled it.
|
On February 06 2015 05:14 Cynry wrote: That namespace discussion and the recent one about i++ or ++i makes me wonder if noobs should really bother learning this kind of optimisation, considering we probably still write suboptimal programs anyway. Like today at school, some guy was telling how setting a variable to 0 is slower than using a xor or something. Does any of this really matter, be it right or not, when we still go through any set of variable 3 times more than is needed ? I don't think so, but maybe I'm wrong..
The general answer to your question is no, most of this stuff does not matter. Pre-optimization is generally considered an evil thing. Those burned by poorly optimized code tend to be scarred in such a way that it warps how one approaches future issues. It's only human nature to try and steer clear of known pitfalls- and when the pitfalls are intangible phantoms in how you perceive your language operating, they can be rather frightening.
As a game programmer I still catch myself gritting my teeth to ignore pitfalls that I ran into on hardware that nobody is even coding for anymore. Old consoles, or outdated Winidows quirks for example. It's tough when your livelihood relies on understanding the pitfalls of the underlying tech. This is especially the case for video games, where milliseconds matter and optimizing on a bit level is sometimes necessary. But still, 99.99% of the time little things that you mentioned do not matter at all. If they did, then we'd have a much larger computing problem on our hands than just performance.
Nowadays, we can trust compilers and interpreters to properly optimize for us. This wasn't always the case. Compilers used to be much crappier. A programmer who does not trust the compiler is a paranoid individual and times were tough in the past. A paranoid programmer could often keep a project on track by steering clear of known bottlenecks. Bottlenecks these days are usually on transfer times or an algorithmic level rather than on a set of inefficient CPU instructions.
Cache, however, remains as important as ever depending on your task. Data sets are increasing at an exponential rate and hardware isn't keeping up with it. Hence the recent trends for data oriented design to work with cache as efficiently as possible.
|
On February 06 2015 05:40 Pirfiktshon wrote:Show nested quote +That namespace discussion and the recent one about i++ or ++i makes me wonder if noobs should really bother learning this kind of optimisation, considering we probably still write suboptimal programs anyway. Like today at school, some guy was telling how setting a variable to 0 is slower than using a xor or something. Does any of this really matter, be it right or not, when we still go through any set of variable 3 times more than is needed ? I don't think so, but maybe I'm wrong.. I've thought this very question and I wound up comparing it to a Car. What would you rather have a car that is clean runs smoothly and you know will always reliably get you from point A to point B or would you rather have a junker that runs like crap and is questionable as to whether it will get you to your destination... Sub-optimal code is like the latter yea most of the time it runs but it'll cost you more time and money when you try to add on to that code or make adjustments... so basically Sub-optimal code winds up being more maintenance and runs like crap in bigger applications.....
While learning to program, optimizing your programs won't help get you better grades, but it is really fun and interesting to see why one program runs faster than another. A clean, well architected program is almost always better than one where all variables are global and meticulous bitwise operations reduce instructions, but if you've already got a clean program running in N seconds, and you want it to run in N-1 seconds, then learning the tricks and methodology behind compiler optimizations is a fun and useful activity.
If you need to write a collision detection algorithm for a game engine, it needs to execute within a 60 Hz loop, and if it goes on too long, the game's fps will drop and look bad. Being able to look at a program's resource requirements and run time, and try to make it fit into real-time requirements is not something a teacher or professor is usually going to address. You'll have to learn it on your own most of the time, and the way to start is by asking silly questions like "is i++ faster than ++i".
Eventually those silly questions will yield real results. For example, when I was early into writing C, I used to wrap fprintf() in a bunch of logging functions which would make my algorithmic code cleaner while still logging what it was doing to a log file for debugging. When I removed the logging wrappers and just used printf instead, I saw a 10 second difference in the run time for my program. At the time, I had no idea why it was slowing down my program so much, so looking into it I found that each one of those logging functions was creating a new stack frame of a 100-byte long char array for storing the logging string, which took a while for the processor to clear.
So, for the ++i question, in 90% of cases it shouldn't matter, but sometimes it does. For the zeroing versus bitwise xor, zeroing is almost always faster as it allows the compiler to optimize code that uses that variable and will likely remove that instruction entirely. The same is true for setting the same variable multiple times. Some languages suck at those optimizations though, so figure out if its actually useful or not for yourself by measuring the difference next time you see it happening a lot in your code. + Show Spoiler +http://stackoverflow.com/questions/4831748/is-i-really-faster-than-i-in-for-loops-in-java
|
On February 06 2015 04:55 darkness wrote: Do you guys spend at least 10 hours in front of computer on a regular basis? If yes, do you get eye twitching? I'm trying to figure out what causes it - too much cola (I've stopped it for the past few days), too much computer screen, lack of sleep, rubbing eyes, etc.
Reducing time in front of computer is hard too as I'm required to spend about 8 hours at work. Any advice? Is your room well and evenly lit? It fixed my recent twitch when i made sure the light is even (lighting was strong on one side).
|
Setting: I had an interview question yesterday in C#, for .net
The guy asked me to fill in pseudocode for a login.
My Answer: I just verified the password, then you had to make an update and an insert. At first I didn't get what was so special about the question, but he hinted that maybe one of the queries would fail. So like with a banking transfer, you'd want to make sure either both queries (withdrawl from your account, deposit to another account) worked or that neither did. How would I handle that?
I eventually answered rollbacks, but I had never used transactions with sql querieis so I didn't mention anything about transactions but he still seemed to be like "alright, at least he knows to use rollbacks".
Is there a better way? Do you need try catch exception handling or is there a better way to check if queries don't work properly?
The database type would be MSSQL but I doubt it'd matter.
|
First query... Well, that's binary, in the sense that you're comparing a username and a hash to a username and a hash. If that fails, you don't log the user in.
Second and third query you wrap in a transaction, which you would do with the SqlTransaction class in C# + MSSQL - then when you commit - i.e. you've reached the point where you want to know if everything is consistent or not, then you do a try catch on that - and if the commits fails, you rollback and tell the user it didn't go as expected.
|
|
|
|