In this post we talked about how some of the items in Effective C++ might apply to Swift.
Many of the entries highlighted some limitations on the part of Swift, so some might think this post was a criticism of Swift. Actually far from it – many of the items in Effective C++ are pointing out dangers of C++ where you can shoot yourself in the foot if you aren’t careful. In most cases, when you look at the equivalent issue in Swift, it’s a non-issue.
For completeness, here is a rundown of every item, what kind of article it is, and how it applies to Swift:
| Item | Danger or benefit? | In Swift |
| 1: View C++ as a federation of languages | Probably a benefit? | Applies the same |
| 2: Prefer consts, enums and inlines to defines | Pre-processor dangerous! | No preprocessor! No reflection or lisp-style macros either tho. |
| 3: Use const whenever possible | Benefit | let and mutating are there, but they only go so far. |
| 4: Make sure that objects are initialized before they’re used | Danger | Fully locked down, you have to initialize variables properly. |
| 5: Know what functions C++ silently writes and calls | Bit of both | Swift writes some init methods automatically, though it’s nowhere near as potentially confusing as C++ |
| 6: Explicitly disallow the use of compiler-generated functions you do not want | Benefit | Doesn’t really apply to Swift |
| 7: Declare destrutors virtual in polymorphic base classes | Danger | Not an issue, every method is virtual in Swift classes. |
| 8: Prevent exceptions from leaving destructors | Danger | No exceptions in Swift! |
| 9: Never call virtual functions during construction or destruction | Danger | Swift’s enforcement of initializing the super and all member variables helps prevent this problem |
| 10: Have assignment operators return a reference to *this | More of a convention | No assignment (or copy constructors) in Swift |
| 11: Handle assignment to self in operator= | Danger | No assignment (or copy constructors) in Swift |
| 12: Copy all parts of an object | Danger | Still dangerous, but without as good tools to fix it (no copy constructors on structs!) |
| 13: Use objects to manage resources | Benefit | ARC + deinit = same benefit! So long as you’re careful about variable capture. |
| 14: Think carefully about copying behavior in resource-managing classes | Good advice | Good advice applies, take it |
| 15: Provide access to raw resources in resource-managing classes | Good advice | Good advice applies, take it |
| 16: Use the same form in corresponding uses of new and delete | Bit of both | No need for explicit memory management in Swift. That’s good, right? |
| 17: Store newer objects in smart pointers in standalone statements | Bit of both | ARC means every pointer in Swift is a smart pointer, so all good. |
| 18: Make interfaces easy to use correctly and hard to use incorrectly | Good advice | Good advice applies, take it |
| 19: Treat class design as type design | Good advice | Good advice applies, take it |
| 20: Prefer pass-by-reference-to-const to pass-by-value | Bit of both | Doesn’t really apply to Swift, though I wish it had proper const support. |
| 21: Don’t try to return a reference when you must return an object. | Danger | ARC means every pointer in Swift is a smart pointer, so all good. |
| 22: Declare data members private | Benefit | No public/private in Swift – yet. It’s coming apparently. |
| 23: Prefer non-member non-friend functions to member functions | Bit of both | Seems to apply the same to Swift. |
| 24: Declare non-member functions when type conversions should apply to all parameters | Bit of both | Type conversion in Swift is very different, and rarely implicit, so this doesn’t really apply. |
| 25: Consider support for a non-throwing swap | Bit of both | No exceptions in Swift, so your swap will definitely be non-throwing. |
| 26: Postpone variable definitions as long as possible | Good advice | Good advice applies, take it |
| 27: Minimize casting | Danger | Swift type casting is a lot safer/saner/more powerful than C++. |
| 28: Avoid returning “handles” to object internals. | Good advice | Good advice applies, take it |
| 29: Strive for exception-safe code | Danger | Swift code is definitely exception-safe. |
| 30: Understand the ins and outs of inlining | Danger | If compilers aren’t better at humans at inlining these days, something has gone wrong. |
| 31: Minimize compilation dependencies between files | Danger | No more headers! |
| 32: Make sure public inheritance models “is-a” | Good advice | Good advice applies, take it |
| 33: Avoid hiding inherited names | Danger | Swift mandates you override a method if it has the same signature as a parent class version |
| 34: Differentiate between inheritance of interface and inheritance of implementation | Good advice | Good advice (mostly) applies, take it |
| 35: Consider alternatives to virtual functions | Good advice | I need to research this one… It probably applies. |
| 36: Never redefine an inherited non-virtual function | Danger | No non-virtual functions in Swift |
| 37: Never redefine a function’s inherited default parameter value | Danger | Swift behaves the same right now but this has been declared a bug in the compiler |
| 38: Model “has-a” or “is-implemented-in-terms-of” through composition. | Good advice | Good advice applies, take it |
| 39: Use private inheritance judiciously | Danger | Private inheritance is a weird C++ thing, don’t sweat it. |
| 40: Use multiple inheritance judiciously. | Danger | No multiple implementation inheritance in Swift. Most people think this is the right idea. |
| 41: Understand implicit interfaces and compile-time polymorphism | Benefit | Swift has compile-time polymorphism through generics much like C++ templates but they differ a lot (C++ templates are crazy powerful crazy complicated) |
| 42: Understand the two meanings of typename | Confusing, if not dangerous | You know how I said C++ templates got crazy complicated? This is part of that. |
| Item 43: Know how to access names in templatized base classes | Confusing, if not dangerous | I need to research this one… probably doesn’t apply. |
| Item 44: Factor parameter-independent code out of templates | Danger | Is it possible Swift generics use could result in code bloat? Would really need some serious LLVM digging to find out. |
| Item 45: Use member function templates to accept “all compatible types.” | Benefit | Swift generics provide much of the same features. Needs a bit more research. |
| Item 46: Define non-member functions inside templates when type conversions are desired | Benefit | Swift is not very implicit type-conversion friendly (opinion probably divided on whether this is a good or bad… I think bad, most probably think good) |
| Item 47: Use traits classes for information about types | Benefit | I need to research this one… Associated types and type constrains in Swift seem related to this. |
| Item 48: Be aware of template metaprogramming | A bizarre C++ rabbit hole | Probably best not to think about it. |
| Items 49-52: New and delete | Various | Swift does have UnsafePointer and malloc so maybe these are kind of topics are not as much of a non-issue as you might think at first. |
| 53: Pay attention to compiler warnings | Good advice | Good advice applies, take it |
| Item 54: Familiarize yourself with the standard library, including TR1 | Benefit | Objective-C, like C++, has a huge library behind it, all of which can be used from Swift. Question is, how much will be ported to a more Swift-like form? Time will tell |
| Item 55: Familiarize yourself with Boost | Beneft | Boost is fantastic. But early indications are, there’s a huge community of Swift developers looking to do similar things. |
[…] for the completists amongst you, this article gives a full rundown of every item in Effective C++ and how it relates to Swift. Note that many of […]